Clean up test files by removing comments
This commit is contained in:
@@ -10,220 +10,145 @@
|
|||||||
|
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
;; ============================================
|
|
||||||
;; Phase 2: Rule Matching Engine Tests
|
|
||||||
;; ============================================
|
|
||||||
|
|
||||||
(deftest rule-matching-by-description-pattern
|
(deftest rule-matching-by-description-pattern
|
||||||
(testing "Rule should match transactions by description pattern"
|
(testing "Rule matching returns sequence for description pattern"
|
||||||
;; Given: Create a transaction rule with description pattern and matching transaction
|
|
||||||
(let [tempids (setup-test-data [{:db/id "rule-1"
|
(let [tempids (setup-test-data [{:db/id "rule-1"
|
||||||
:transaction-rule/description "HOME DEPOT"
|
:transaction-rule/description "HOME DEPOT"
|
||||||
:transaction-rule/note "Home improvement"
|
:transaction-rule/note "Home improvement"
|
||||||
:transaction-rule/amount-gte 50.0
|
:transaction-rule/amount-gte 50.0
|
||||||
:transaction-rule/amount-lte 500.0}])
|
:transaction-rule/amount-lte 500.0}])]
|
||||||
db (dc/db conn)]
|
|
||||||
;; When: Find transactions matching the rule
|
|
||||||
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/description "HOME DEPOT"}
|
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/description "HOME DEPOT"}
|
||||||
:clients nil})]
|
:clients nil})]
|
||||||
;; Then: Matching logic is accessible (we'll test actual matching with full transaction data)
|
|
||||||
(is (seq? matches))))))
|
(is (seq? matches))))))
|
||||||
|
|
||||||
(deftest rule-matching-returns-empty-for-no-matches
|
(deftest rule-matching-returns-empty-for-no-matches
|
||||||
(testing "Rule matching should return empty when no transactions match"
|
(testing "Rule matching returns empty sequence when no transactions match"
|
||||||
;; Given: Create a rule that won't match any transactions
|
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/description "XYZ-NON-EXISTENT"}
|
||||||
(let [db (dc/db conn)]
|
:clients nil})]
|
||||||
;; When: Match against non-existent description
|
(is (seq? matches))
|
||||||
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/description "XYZ-NON-EXISTENT"}
|
(is (= 0 (count matches))))))
|
||||||
:clients nil})]
|
|
||||||
;; Then: Returns empty sequence
|
|
||||||
(is (seq? matches))
|
|
||||||
(is (= 0 (count matches)))))))
|
|
||||||
|
|
||||||
(deftest validate-transaction-rule-accepts-valid-data
|
(deftest validate-transaction-rule-accepts-valid-data
|
||||||
(testing "Transaction rule validation should accept valid data"
|
(testing "Validation accepts valid data with 100% account allocation"
|
||||||
;; Given: Valid form params with accounts that sum to 100%
|
|
||||||
(let [form-params {:transaction-rule/description "Test Rule"
|
(let [form-params {:transaction-rule/description "Test Rule"
|
||||||
:transaction-rule/note "Test note"
|
:transaction-rule/note "Test note"
|
||||||
:transaction-rule/amount-gte "100"
|
:transaction-rule/amount-gte "100"
|
||||||
:transaction-rule/amount-lte "500"
|
:transaction-rule/amount-lte "500"
|
||||||
:transaction-rule/accounts [{:transaction-rule-account/percentage 1.0}]}]
|
:transaction-rule/accounts [{:transaction-rule-account/percentage 1.0}]}]
|
||||||
;; When: Validate the rule
|
|
||||||
;; Then: No exception thrown for valid data
|
|
||||||
(is (nil? (sut/validate-transaction-rule form-params))))))
|
(is (nil? (sut/validate-transaction-rule form-params))))))
|
||||||
|
|
||||||
(deftest validate-transaction-rule-rejects-invalid-accounts-total
|
(deftest validate-transaction-rule-rejects-invalid-accounts-total
|
||||||
(testing "Transaction rule validation should reject accounts that don't sum to 100%"
|
(testing "Validation rejects accounts that do not sum to 100%"
|
||||||
;; Given: Form params with accounts totaling less than 100%
|
|
||||||
(let [form-params {:transaction-rule/description "Test Rule"
|
(let [form-params {:transaction-rule/description "Test Rule"
|
||||||
:transaction-rule/note "Test note"
|
:transaction-rule/note "Test note"
|
||||||
:transaction-rule/accounts [{:transaction-rule-account/percentage 0.5}]}]
|
:transaction-rule/accounts [{:transaction-rule-account/percentage 0.5}]}]
|
||||||
;; When: Validate the rule
|
|
||||||
;; Then: Exception thrown for invalid accounts total
|
|
||||||
(is (thrown? Exception (sut/validate-transaction-rule form-params))))))
|
(is (thrown? Exception (sut/validate-transaction-rule form-params))))))
|
||||||
|
|
||||||
(deftest rule-matching-by-amount-range
|
(deftest rule-matching-by-amount-range
|
||||||
(testing "Rule matching should filter by amount range"
|
(testing "Rule matching filters by amount range"
|
||||||
;; Given: Rule with amount constraints
|
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/amount-gte 100.0
|
||||||
(let [db (dc/db conn)]
|
:transaction-rule/amount-lte 200.0}
|
||||||
;; When: Match with amount criteria
|
:clients nil})]
|
||||||
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/amount-gte 100.0
|
(is (seq? matches)))))
|
||||||
:transaction-rule/amount-lte 200.0}
|
|
||||||
:clients nil})]
|
|
||||||
;; Then: Returns sequence (actual matching depends on transaction data)
|
|
||||||
(is (seq? matches))))))
|
|
||||||
|
|
||||||
(deftest rule-matching-by-bank-account
|
(deftest rule-matching-by-bank-account
|
||||||
(testing "Rule matching should filter by bank account"
|
(testing "Rule matching filters by bank account"
|
||||||
;; Given: Rule with bank account
|
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/bank-account 12345}
|
||||||
(let [db (dc/db conn)]
|
:clients nil})]
|
||||||
;; When: Match with bank account criteria
|
(is (seq? matches)))))
|
||||||
(let [matches (sut/transactions-matching-rule {:entity {:transaction-rule/bank-account 12345}
|
|
||||||
:clients nil})]
|
|
||||||
;; Then: Returns sequence
|
|
||||||
(is (seq? matches))))))
|
|
||||||
|
|
||||||
;; ============================================
|
|
||||||
;; Route Handler Tests
|
|
||||||
;; ============================================
|
|
||||||
|
|
||||||
(deftest page-route-returns-html-response
|
(deftest page-route-returns-html-response
|
||||||
(testing "Page route should return HTML response"
|
(testing "Page route returns HTML response"
|
||||||
;; Given: Admin request
|
(let [request {:identity (admin-token)}
|
||||||
(let [request {:identity (admin-token)}]
|
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/page) request)]
|
||||||
;; When: Call page route
|
(is (= 200 (:status response)))
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/page) request)]
|
(is (string? (apply str (:body response)))))))
|
||||||
;; Then: Returns HTML response
|
|
||||||
(is (= 200 (:status response)))
|
|
||||||
(is (string? (apply str (:body response))))))))
|
|
||||||
|
|
||||||
(deftest table-route-returns-table-data
|
(deftest table-route-returns-table-data
|
||||||
(testing "Table route should return table data for HTMX"
|
(testing "Table route returns table data for HTMX"
|
||||||
;; Given: Setup test data and admin request
|
|
||||||
(setup-test-data [{:db/id "rule-1"
|
(setup-test-data [{:db/id "rule-1"
|
||||||
:transaction-rule/description "Test Rule"
|
:transaction-rule/description "Test Rule"
|
||||||
:transaction-rule/note "Test note"}])
|
:transaction-rule/note "Test note"}])
|
||||||
(let [request {:identity (admin-token)
|
(let [request {:identity (admin-token)
|
||||||
:query-params {:page 1 :per-page 10}}]
|
:query-params {:page 1 :per-page 10}}
|
||||||
;; When: Call table route
|
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/table) request)]
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/table) request)]
|
(is (= 200 (:status response))))))
|
||||||
;; Then: Returns HTML table response
|
|
||||||
(is (= 200 (:status response)))))))
|
|
||||||
|
|
||||||
(deftest delete-route-deletes-rule
|
(deftest delete-route-deletes-rule
|
||||||
(testing "Delete route should remove transaction rule"
|
(testing "Delete route removes transaction rule from database"
|
||||||
;; Given: Create a transaction rule
|
|
||||||
(let [tempids (setup-test-data [{:db/id "rule-to-delete"
|
(let [tempids (setup-test-data [{:db/id "rule-to-delete"
|
||||||
:transaction-rule/description "Rule to Delete"
|
:transaction-rule/description "Rule to Delete"
|
||||||
:transaction-rule/note "Will be deleted"}])
|
:transaction-rule/note "Will be deleted"}])
|
||||||
rule-id (get tempids "rule-to-delete")
|
rule-id (get tempids "rule-to-delete")
|
||||||
request {:identity (admin-token)
|
request {:identity (admin-token)
|
||||||
:route-params {:db/id rule-id}}]
|
:route-params {:db/id rule-id}}]
|
||||||
(let [db (dc/db conn)
|
(is (= 1 (count (dc/q '[:find ?e
|
||||||
remaining (dc/q '[:find ?e
|
|
||||||
:where [?e :transaction-rule/description "Rule to Delete"]]
|
:where [?e :transaction-rule/description "Rule to Delete"]]
|
||||||
db)]
|
(dc/db conn)))))
|
||||||
(is (= 1 (count remaining))))
|
|
||||||
;; When: Call delete route
|
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/delete) request)]
|
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/delete) request)]
|
||||||
;; Then: Rule is deleted
|
|
||||||
|
|
||||||
(is (= 200 (:status response)))
|
(is (= 200 (:status response)))
|
||||||
;; And: Rule no longer exists in database
|
(is (= 0 (count (dc/q '[:find ?e
|
||||||
(let [db (dc/db conn)
|
|
||||||
remaining (dc/q '[:find ?e
|
|
||||||
:where [?e :transaction-rule/description "Rule to Delete"]]
|
:where [?e :transaction-rule/description "Rule to Delete"]]
|
||||||
db)]
|
(dc/db conn)))))))))
|
||||||
(is (= 0 (count remaining))))))))
|
|
||||||
|
|
||||||
(deftest check-badges-route-works
|
(deftest check-badges-route-works
|
||||||
(testing "Check badges route should return badge status"
|
(testing "Check badges route returns badge status map"
|
||||||
;; Given: Admin request
|
|
||||||
(let [request {:identity (admin-token)
|
(let [request {:identity (admin-token)
|
||||||
:query-params {}}]
|
:query-params {}}
|
||||||
;; When: Call check-badges route
|
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/check-badges) request)]
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/check-badges) request)]
|
(is (map? response)))))
|
||||||
;; Then: Returns response
|
|
||||||
(is (map? response))))))
|
|
||||||
|
|
||||||
(deftest edit-dialog-route-returns-dialog
|
(deftest edit-dialog-route-returns-dialog
|
||||||
(testing "Edit dialog route should return edit dialog for existing rule"
|
(testing "Edit dialog route returns HTML dialog for existing rule"
|
||||||
;; Given: Create a transaction rule
|
|
||||||
(let [tempids (setup-test-data [{:db/id "rule-to-edit"
|
(let [tempids (setup-test-data [{:db/id "rule-to-edit"
|
||||||
:transaction-rule/description "Rule to Edit"
|
:transaction-rule/description "Rule to Edit"
|
||||||
:transaction-rule/note "Edit me"}])
|
:transaction-rule/note "Edit me"}])
|
||||||
rule-id (get tempids "rule-to-edit")
|
rule-id (get tempids "rule-to-edit")
|
||||||
request {:identity (admin-token)
|
request {:identity (admin-token)
|
||||||
:route-params {:db/id rule-id}}]
|
:route-params {:db/id rule-id}}
|
||||||
;; When: Call edit-dialog route
|
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/edit-dialog) request)]
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/edit-dialog) request)]
|
(is (= 200 (:status response)))
|
||||||
;; Then: Returns HTML dialog response
|
(is (string? (apply str (:body response)))))))
|
||||||
(is (= 200 (:status response)))
|
|
||||||
(is (string? (apply str (:body response))))))))
|
|
||||||
|
|
||||||
(deftest account-typeahead-route-works
|
(deftest account-typeahead-route-works
|
||||||
(testing "Account typeahead route should return account suggestions"
|
(testing "Account typeahead route returns account suggestions HTML"
|
||||||
;; Given: Admin request with search params
|
|
||||||
(let [request {:identity (admin-token)
|
(let [request {:identity (admin-token)
|
||||||
:query-params {:name "Test"}}]
|
:query-params {:name "Test"}}
|
||||||
;; When: Call account-typeahead route
|
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/account-typeahead) request)]
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/account-typeahead) request)]
|
(is (= 200 (:status response)))
|
||||||
;; Then: Returns HTML response with typeahead
|
(is (string? (apply str (:body response)))))))
|
||||||
(is (= 200 (:status response)))
|
|
||||||
(is (string? (apply str (:body response))))))))
|
|
||||||
|
|
||||||
(deftest location-select-route-works
|
(deftest location-select-route-works
|
||||||
(testing "Location select route should return location selector"
|
(testing "Location select route returns location selector HTML"
|
||||||
;; Given: Admin request
|
|
||||||
(let [request {:identity (admin-token)
|
(let [request {:identity (admin-token)
|
||||||
:query-params {:name "location"}}]
|
:query-params {:name "location"}}
|
||||||
;; When: Call location-select route
|
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/location-select) request)]
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/location-select) request)]
|
(is (= 200 (:status response)))
|
||||||
;; Then: Returns HTML response
|
(is (string? (apply str (:body response)))))))
|
||||||
(is (= 200 (:status response)))
|
|
||||||
(is (string? (apply str (:body response))))))))
|
|
||||||
|
|
||||||
(deftest execute-dialog-route-works
|
(deftest execute-dialog-route-works
|
||||||
(testing "Execute dialog route should return execution dialog"
|
(testing "Execute dialog route returns execution dialog HTML"
|
||||||
;; Given: Create a transaction rule
|
|
||||||
(let [tempids (setup-test-data [{:db/id "rule-to-execute"
|
(let [tempids (setup-test-data [{:db/id "rule-to-execute"
|
||||||
:transaction-rule/description "Rule to Execute"
|
:transaction-rule/description "Rule to Execute"
|
||||||
:transaction-rule/note "Execute me"}])
|
:transaction-rule/note "Execute me"}])
|
||||||
rule-id (get tempids "rule-to-execute")
|
rule-id (get tempids "rule-to-execute")
|
||||||
request {:identity (admin-token)
|
request {:identity (admin-token)
|
||||||
:route-params {:db/id rule-id}}]
|
:route-params {:db/id rule-id}}
|
||||||
;; When: Call execute-dialog route
|
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/execute-dialog) request)]
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/execute-dialog) request)]
|
(is (= 200 (:status response)))
|
||||||
;; Then: Returns HTML dialog
|
(is (string? (apply str (:body response)))))))
|
||||||
(is (= 200 (:status response)))
|
|
||||||
(is (string? (apply str (:body response))))))))
|
|
||||||
|
|
||||||
(deftest new-dialog-route-returns-empty-form
|
(deftest new-dialog-route-returns-empty-form
|
||||||
(testing "New dialog route should return empty form for new rule"
|
(testing "New dialog route returns empty form HTML for new rule"
|
||||||
;; Given: Admin request
|
(let [request {:identity (admin-token)}
|
||||||
(let [request {:identity (admin-token)}]
|
response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/new-dialog) request)]
|
||||||
;; When: Call new-dialog route
|
(is (= 200 (:status response)))
|
||||||
(let [response ((get sut/key->handler :auto-ap.routes.admin.transaction-rules/new-dialog) request)]
|
(is (string? (apply str (:body response)))))))
|
||||||
;; Then: Returns HTML form
|
|
||||||
(is (= 200 (:status response)))
|
|
||||||
(is (string? (apply str (:body response))))))))
|
|
||||||
|
|
||||||
;; ============================================
|
|
||||||
;; Phase 5: CRUD and Security Tests
|
|
||||||
;; ============================================
|
|
||||||
|
|
||||||
(deftest non-admin-cannot-execute-rules
|
(deftest non-admin-cannot-execute-rules
|
||||||
(testing "Non-admin users should not be able to execute transaction rules"
|
(testing "Non-admin users cannot execute transaction rules"
|
||||||
(let [user-identity {:user/role "user" :user/name "Test User"}]
|
(is true "Role checking is done at middleware level")))
|
||||||
;; When: Non-admin attempts to execute rule
|
|
||||||
;; Note: In real scenario, wrap-admin middleware would block this
|
|
||||||
;; This test documents that the function itself doesn't check roles
|
|
||||||
(is true "Role checking is done at middleware level"))))
|
|
||||||
|
|
||||||
(deftest execute-validates-before-applying
|
(deftest execute-validates-before-applying
|
||||||
(testing "Rule execution should validate before applying to transactions"
|
(testing "Rule execution validates before applying to transactions"
|
||||||
;; Given: Invalid rule execution request
|
(is true "Validation occurs in execute function")))
|
||||||
(let [admin-identity (admin-token)]
|
|
||||||
;; When: Attempt to execute with no transactions selected
|
|
||||||
;; Then: Should handle gracefully
|
|
||||||
(is true "Validation occurs in execute function"))))
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
(defn create-vendor
|
(defn create-vendor
|
||||||
"Create a vendor with a unique temp id"
|
|
||||||
[name & {:as attrs}]
|
[name & {:as attrs}]
|
||||||
(merge
|
(merge
|
||||||
{:db/id (str "vendor-" (java.util.UUID/randomUUID))
|
{:db/id (str "vendor-" (java.util.UUID/randomUUID))
|
||||||
@@ -24,45 +23,32 @@
|
|||||||
:vendor/default-account "test-account-id"}
|
:vendor/default-account "test-account-id"}
|
||||||
attrs))
|
attrs))
|
||||||
|
|
||||||
;; ============================================
|
|
||||||
;; Grid/List Tests
|
|
||||||
;; ============================================
|
|
||||||
|
|
||||||
(deftest vendor-grid-loads-with-empty-database
|
(deftest vendor-grid-loads-with-empty-database
|
||||||
(testing "Vendor grid should handle empty database gracefully"
|
(testing "Vendor grid should handle empty database gracefully"
|
||||||
;; When: Fetch the vendors page with no data
|
|
||||||
(let [[vendors matching-count] (sut/fetch-page {:query-params {:page 1 :per-page 10}})]
|
(let [[vendors matching-count] (sut/fetch-page {:query-params {:page 1 :per-page 10}})]
|
||||||
;; Then: Returns empty results without error
|
|
||||||
(is (seq? vendors))
|
(is (seq? vendors))
|
||||||
(is (number? matching-count))
|
(is (number? matching-count))
|
||||||
(is (= 0 (count vendors))))))
|
(is (= 0 (count vendors))))))
|
||||||
|
|
||||||
(deftest vendor-fetch-ids-returns-correct-structure
|
(deftest vendor-fetch-ids-returns-correct-structure
|
||||||
(testing "fetch-ids should return properly structured results"
|
(testing "fetch-ids should return properly structured results"
|
||||||
;; Given: Setup test data with vendors using unique IDs
|
|
||||||
(setup-test-data [(create-vendor "Test Vendor 1")
|
(setup-test-data [(create-vendor "Test Vendor 1")
|
||||||
(create-vendor "Test Vendor 2")])
|
(create-vendor "Test Vendor 2")])
|
||||||
(let [db (dc/db conn)]
|
(let [db (dc/db conn)
|
||||||
;; When: Call fetch-ids
|
result (sut/fetch-ids db {:query-params {:page 1 :per-page 10}})]
|
||||||
(let [result (sut/fetch-ids db {:query-params {:page 1 :per-page 10}})]
|
(is (contains? result :ids))
|
||||||
;; Then: Result has expected structure with :ids and :count
|
(is (contains? result :count))
|
||||||
(is (contains? result :ids))
|
(is (seq? (:ids result)))
|
||||||
(is (contains? result :count))
|
(is (number? (:count result)))
|
||||||
(is (seq? (:ids result)))
|
(is (>= (:count result) 3)))))
|
||||||
(is (number? (:count result)))
|
|
||||||
(is (>= (:count result) 3)))))) ; 2 new + 1 from setup
|
|
||||||
|
|
||||||
(deftest vendor-fetch-page-returns-vendors
|
(deftest vendor-fetch-page-returns-vendors
|
||||||
(testing "fetch-page should return vendors with proper structure"
|
(testing "fetch-page should return vendors with proper structure"
|
||||||
;; Given: Setup test data
|
|
||||||
(setup-test-data [(create-vendor "Page Test Vendor 1")
|
(setup-test-data [(create-vendor "Page Test Vendor 1")
|
||||||
(create-vendor "Page Test Vendor 2")])
|
(create-vendor "Page Test Vendor 2")])
|
||||||
;; When: Fetch the vendors page
|
|
||||||
(let [[vendors matching-count] (sut/fetch-page {:query-params {:page 1 :per-page 10}})]
|
(let [[vendors matching-count] (sut/fetch-page {:query-params {:page 1 :per-page 10}})]
|
||||||
;; Then: Vendor table displays with data
|
|
||||||
(is (number? matching-count))
|
(is (number? matching-count))
|
||||||
(is (>= matching-count 3)) ; 2 new + 1 from setup
|
(is (>= matching-count 3))
|
||||||
;; Verify vendors have required attributes
|
|
||||||
(when-some [vendor (first vendors)]
|
(when-some [vendor (first vendors)]
|
||||||
(is (contains? vendor :db/id))
|
(is (contains? vendor :db/id))
|
||||||
(is (contains? vendor :vendor/name))
|
(is (contains? vendor :vendor/name))
|
||||||
@@ -70,94 +56,70 @@
|
|||||||
|
|
||||||
(deftest vendor-hydrate-results-works
|
(deftest vendor-hydrate-results-works
|
||||||
(testing "hydrate-results should properly hydrate vendor data"
|
(testing "hydrate-results should properly hydrate vendor data"
|
||||||
;; Given: Setup test data with unique vendor ID
|
|
||||||
(let [vendor-temp-id (str "vendor-" (rand-int 100000))
|
(let [vendor-temp-id (str "vendor-" (rand-int 100000))
|
||||||
tempids (setup-test-data [(assoc (create-vendor "Hydrate Test Vendor")
|
tempids (setup-test-data [(assoc (create-vendor "Hydrate Test Vendor")
|
||||||
:db/id vendor-temp-id)])
|
:db/id vendor-temp-id)])
|
||||||
db (dc/db conn)
|
db (dc/db conn)
|
||||||
vendor-id (get tempids vendor-temp-id)]
|
vendor-id (get tempids vendor-temp-id)
|
||||||
;; When: Hydrate the vendor
|
hydrated (sut/hydrate-results [vendor-id] db {})]
|
||||||
(let [hydrated (sut/hydrate-results [vendor-id] db {})]
|
(is (= 1 (count hydrated)))
|
||||||
;; Then: Vendor is properly hydrated
|
(let [vendor (first hydrated)]
|
||||||
(is (= 1 (count hydrated)))
|
(is (= vendor-id (:db/id vendor)))
|
||||||
(let [vendor (first hydrated)]
|
(is (= "Hydrate Test Vendor" (:vendor/name vendor)))
|
||||||
(is (= vendor-id (:db/id vendor)))
|
(is (contains? vendor :vendor/default-account))))))
|
||||||
(is (= "Hydrate Test Vendor" (:vendor/name vendor)))
|
|
||||||
(is (contains? vendor :vendor/default-account)))))))
|
|
||||||
|
|
||||||
;; ============================================
|
|
||||||
;; Vendor Merge Tests
|
|
||||||
;; ============================================
|
|
||||||
|
|
||||||
(deftest vendor-merge-transfers-references
|
(deftest vendor-merge-transfers-references
|
||||||
(testing "Vendor merge should transfer all references from source to target"
|
(testing "Vendor merge should transfer all references from source to target"
|
||||||
(let [admin-identity (admin-token)]
|
(let [admin-identity (admin-token)
|
||||||
;; Given: Create source and target vendors with unique IDs
|
source-temp-id (str "vendor-source-" (rand-int 100000))
|
||||||
(let [source-temp-id (str "vendor-source-" (rand-int 100000))
|
target-temp-id (str "vendor-target-" (rand-int 100000))
|
||||||
target-temp-id (str "vendor-target-" (rand-int 100000))
|
tempids (setup-test-data [(assoc (create-vendor "Source Vendor")
|
||||||
tempids (setup-test-data [(assoc (create-vendor "Source Vendor")
|
:db/id source-temp-id)
|
||||||
:db/id source-temp-id)
|
(assoc (create-vendor "Target Vendor")
|
||||||
(assoc (create-vendor "Target Vendor")
|
:db/id target-temp-id)])
|
||||||
:db/id target-temp-id)])
|
source-vendor-id (get tempids source-temp-id)
|
||||||
source-vendor-id (get tempids source-temp-id)
|
target-vendor-id (get tempids target-temp-id)
|
||||||
target-vendor-id (get tempids target-temp-id)]
|
result (sut/merge-submit {:form-params {:source-vendor source-vendor-id
|
||||||
;; When: Merge source into target
|
:target-vendor target-vendor-id}
|
||||||
(let [result (sut/merge-submit {:form-params {:source-vendor source-vendor-id
|
:request-method :put
|
||||||
:target-vendor target-vendor-id}
|
:identity admin-identity})]
|
||||||
:request-method :put
|
(is (= 200 (:status result)))
|
||||||
:identity admin-identity})]
|
(let [db (dc/db conn)
|
||||||
;; Then: Success response
|
remaining-sources (dc/q '[:find ?e
|
||||||
(is (= 200 (:status result)))
|
:where [?e :vendor/name "Source Vendor"]]
|
||||||
|
db)]
|
||||||
;; And: Source vendor should be deleted
|
(is (= 0 (count remaining-sources)))))))
|
||||||
(let [db (dc/db conn)
|
|
||||||
remaining-sources (dc/q '[:find ?e
|
|
||||||
:where [?e :vendor/name "Source Vendor"]]
|
|
||||||
db)]
|
|
||||||
(is (= 0 (count remaining-sources)))))))))
|
|
||||||
|
|
||||||
(deftest vendor-merge-same-vendor-rejected
|
(deftest vendor-merge-same-vendor-rejected
|
||||||
(testing "Vendor merge should reject when source and target are the same"
|
(testing "Vendor merge should reject when source and target are the same"
|
||||||
(let [admin-identity (admin-token)]
|
(let [admin-identity (admin-token)
|
||||||
;; Given: Create a vendor with unique ID
|
vendor-temp-id (str "vendor-solo-" (rand-int 100000))
|
||||||
(let [vendor-temp-id (str "vendor-solo-" (rand-int 100000))
|
tempids (setup-test-data [(assoc (create-vendor "Solo Vendor")
|
||||||
tempids (setup-test-data [(assoc (create-vendor "Solo Vendor")
|
:db/id vendor-temp-id)])
|
||||||
:db/id vendor-temp-id)])
|
vendor-id (get tempids vendor-temp-id)]
|
||||||
vendor-id (get tempids vendor-temp-id)]
|
(is (thrown-with-msg? clojure.lang.ExceptionInfo
|
||||||
;; When: Attempt to merge vendor with itself
|
#"Please select two different vendors"
|
||||||
;; Then: Exception is thrown with validation error
|
(sut/merge-submit {:form-params {:source-vendor vendor-id
|
||||||
(is (thrown-with-msg? clojure.lang.ExceptionInfo
|
:target-vendor vendor-id}
|
||||||
#"Please select two different vendors"
|
:request-method :put
|
||||||
(sut/merge-submit {:form-params {:source-vendor vendor-id
|
:identity admin-identity}))))))
|
||||||
:target-vendor vendor-id}
|
|
||||||
:request-method :put
|
|
||||||
:identity admin-identity})))))))
|
|
||||||
|
|
||||||
(deftest vendor-merge-invalid-vendor-handled
|
(deftest vendor-merge-invalid-vendor-handled
|
||||||
(testing "Vendor merge should handle invalid vendor IDs gracefully"
|
(testing "Vendor merge should handle invalid vendor IDs gracefully"
|
||||||
(let [admin-identity (admin-token)]
|
(let [admin-identity (admin-token)
|
||||||
;; Given: Create a target vendor
|
target-temp-id (str "vendor-target-" (rand-int 100000))
|
||||||
(let [target-temp-id (str "vendor-target-" (rand-int 100000))
|
tempids (setup-test-data [(assoc (create-vendor "Valid Target Vendor")
|
||||||
tempids (setup-test-data [(assoc (create-vendor "Valid Target Vendor")
|
:db/id target-temp-id)])
|
||||||
:db/id target-temp-id)])
|
target-vendor-id (get tempids target-temp-id)
|
||||||
target-vendor-id (get tempids target-temp-id)
|
invalid-source-id 999999999
|
||||||
;; Invalid source vendor ID
|
result (sut/merge-submit {:form-params {:source-vendor invalid-source-id
|
||||||
invalid-source-id 999999999]
|
:target-vendor target-vendor-id}
|
||||||
;; When: Attempt merge with invalid source
|
:request-method :put
|
||||||
(let [result (sut/merge-submit {:form-params {:source-vendor invalid-source-id
|
:identity admin-identity})]
|
||||||
:target-vendor target-vendor-id}
|
(is (= 200 (:status result))))))
|
||||||
:request-method :put
|
|
||||||
:identity admin-identity})]
|
|
||||||
;; Then: Should still succeed (Datomic handles non-existent retract gracefully)
|
|
||||||
(is (= 200 (:status result))))))))
|
|
||||||
|
|
||||||
;; ============================================
|
|
||||||
;; Vendor Data Structure Tests
|
|
||||||
;; ============================================
|
|
||||||
|
|
||||||
(deftest vendor-hydration-includes-all-fields
|
(deftest vendor-hydration-includes-all-fields
|
||||||
(testing "Vendor hydration should include all required fields"
|
(testing "Vendor hydration should include all required fields"
|
||||||
;; Given: Create a comprehensive vendor
|
|
||||||
(let [vendor-temp-id (str "vendor-complete-" (rand-int 100000))
|
(let [vendor-temp-id (str "vendor-complete-" (rand-int 100000))
|
||||||
tempids (setup-test-data [(assoc (create-vendor "Complete Vendor"
|
tempids (setup-test-data [(assoc (create-vendor "Complete Vendor"
|
||||||
:vendor/print-as "CV Print Name"
|
:vendor/print-as "CV Print Name"
|
||||||
@@ -165,13 +127,11 @@
|
|||||||
:vendor/terms 30)
|
:vendor/terms 30)
|
||||||
:db/id vendor-temp-id)])
|
:db/id vendor-temp-id)])
|
||||||
db (dc/db conn)
|
db (dc/db conn)
|
||||||
vendor-id (get tempids vendor-temp-id)]
|
vendor-id (get tempids vendor-temp-id)
|
||||||
;; When: Fetch and hydrate the vendor
|
hydrated (sut/hydrate-results [vendor-id] db {})
|
||||||
(let [hydrated (sut/hydrate-results [vendor-id] db {})
|
vendor (first hydrated)]
|
||||||
vendor (first hydrated)]
|
(is (some? vendor))
|
||||||
;; Then: All fields are present
|
(is (= "Complete Vendor" (:vendor/name vendor)))
|
||||||
(is (some? vendor))
|
(is (= "CV Print Name" (:vendor/print-as vendor)))
|
||||||
(is (= "Complete Vendor" (:vendor/name vendor)))
|
(is (= false (:vendor/hidden vendor)))
|
||||||
(is (= "CV Print Name" (:vendor/print-as vendor)))
|
(is (= 30 (:vendor/terms vendor))))))
|
||||||
(is (= false (:vendor/hidden vendor)))
|
|
||||||
(is (= 30 (:vendor/terms vendor)))))))
|
|
||||||
|
|||||||
Reference in New Issue
Block a user