feat(tests): Add comprehensive tests for SSR admin vendors module
Add 8 BDD-style tests for the vendors module covering grid/list operations and vendor merge functionality. Tests follow established patterns from accounts_test.clj and include proper database verification. Tests Implemented: - vendor-grid-loads-with-empty-database - vendor-fetch-ids-returns-correct-structure - vendor-fetch-page-returns-vendors - vendor-hydrate-results-works - vendor-merge-transfers-references - vendor-merge-same-vendor-rejected - vendor-merge-invalid-vendor-handled - vendor-hydration-includes-all-fields Key Implementation Details: - Uses setup-test-data helper with unique temp IDs - Tests focus on public interface (fetch-page, merge-submit) - Follows BDD Given/When/Then pattern - All 8 tests passing (26 assertions) Documentation: - Created implementation plan in docs/plans/ - Documented solution patterns in docs/solutions/ - Created code review todos for future improvements 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
177
test/clj/auto_ap/ssr/admin/vendors_test.clj
Normal file
177
test/clj/auto_ap/ssr/admin/vendors_test.clj
Normal file
@@ -0,0 +1,177 @@
|
||||
(ns auto-ap.ssr.admin.vendors-test
|
||||
(:require
|
||||
[auto-ap.datomic :refer [conn]]
|
||||
[auto-ap.integration.util :refer [admin-token
|
||||
setup-test-data
|
||||
test-account
|
||||
test-client
|
||||
test-vendor
|
||||
user-token
|
||||
wrap-setup]]
|
||||
[auto-ap.ssr.admin.vendors :as sut]
|
||||
[clojure.string :as str]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[datomic.api :as dc]))
|
||||
|
||||
(use-fixtures :each wrap-setup)
|
||||
|
||||
(defn create-vendor
|
||||
"Create a vendor with a unique temp id"
|
||||
[name & {:as attrs}]
|
||||
(merge
|
||||
{:db/id (str "vendor-" (java.util.UUID/randomUUID))
|
||||
:vendor/name name
|
||||
:vendor/default-account "test-account-id"}
|
||||
attrs))
|
||||
|
||||
;; ============================================
|
||||
;; Grid/List Tests
|
||||
;; ============================================
|
||||
|
||||
(deftest vendor-grid-loads-with-empty-database
|
||||
(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}})]
|
||||
;; Then: Returns empty results without error
|
||||
(is (seq? vendors))
|
||||
(is (number? matching-count))
|
||||
(is (= 0 (count vendors))))))
|
||||
|
||||
(deftest vendor-fetch-ids-returns-correct-structure
|
||||
(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")
|
||||
(create-vendor "Test Vendor 2")])
|
||||
(let [db (dc/db conn)]
|
||||
;; When: Call fetch-ids
|
||||
(let [result (sut/fetch-ids db {:query-params {:page 1 :per-page 10}})]
|
||||
;; Then: Result has expected structure with :ids and :count
|
||||
(is (contains? result :ids))
|
||||
(is (contains? result :count))
|
||||
(is (seq? (:ids result)))
|
||||
(is (number? (:count result)))
|
||||
(is (>= (:count result) 3)))))) ; 2 new + 1 from setup
|
||||
|
||||
(deftest vendor-fetch-page-returns-vendors
|
||||
(testing "fetch-page should return vendors with proper structure"
|
||||
;; Given: Setup test data
|
||||
(setup-test-data [(create-vendor "Page Test Vendor 1")
|
||||
(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}})]
|
||||
;; Then: Vendor table displays with data
|
||||
(is (number? matching-count))
|
||||
(is (>= matching-count 3)) ; 2 new + 1 from setup
|
||||
;; Verify vendors have required attributes
|
||||
(when-some [vendor (first vendors)]
|
||||
(is (contains? vendor :db/id))
|
||||
(is (contains? vendor :vendor/name))
|
||||
(is (contains? vendor :vendor/default-account))))))
|
||||
|
||||
(deftest vendor-hydrate-results-works
|
||||
(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))
|
||||
tempids (setup-test-data [(assoc (create-vendor "Hydrate Test Vendor")
|
||||
:db/id vendor-temp-id)])
|
||||
db (dc/db conn)
|
||||
vendor-id (get tempids vendor-temp-id)]
|
||||
;; When: Hydrate the vendor
|
||||
(let [hydrated (sut/hydrate-results [vendor-id] db {})]
|
||||
;; Then: Vendor is properly hydrated
|
||||
(is (= 1 (count hydrated)))
|
||||
(let [vendor (first hydrated)]
|
||||
(is (= vendor-id (:db/id vendor)))
|
||||
(is (= "Hydrate Test Vendor" (:vendor/name vendor)))
|
||||
(is (contains? vendor :vendor/default-account)))))))
|
||||
|
||||
;; ============================================
|
||||
;; Vendor Merge Tests
|
||||
;; ============================================
|
||||
|
||||
(deftest vendor-merge-transfers-references
|
||||
(testing "Vendor merge should transfer all references from source to target"
|
||||
(let [admin-identity (admin-token)]
|
||||
;; Given: Create source and target vendors with unique IDs
|
||||
(let [source-temp-id (str "vendor-source-" (rand-int 100000))
|
||||
target-temp-id (str "vendor-target-" (rand-int 100000))
|
||||
tempids (setup-test-data [(assoc (create-vendor "Source Vendor")
|
||||
:db/id source-temp-id)
|
||||
(assoc (create-vendor "Target Vendor")
|
||||
:db/id target-temp-id)])
|
||||
source-vendor-id (get tempids source-temp-id)
|
||||
target-vendor-id (get tempids target-temp-id)]
|
||||
;; When: Merge source into target
|
||||
(let [result (sut/merge-submit {:form-params {:source-vendor source-vendor-id
|
||||
:target-vendor target-vendor-id}
|
||||
:request-method :put
|
||||
:identity admin-identity})]
|
||||
;; Then: Success response
|
||||
(is (= 200 (:status result)))
|
||||
|
||||
;; And: Source vendor should be deleted
|
||||
(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
|
||||
(testing "Vendor merge should reject when source and target are the same"
|
||||
(let [admin-identity (admin-token)]
|
||||
;; Given: Create a vendor with unique ID
|
||||
(let [vendor-temp-id (str "vendor-solo-" (rand-int 100000))
|
||||
tempids (setup-test-data [(assoc (create-vendor "Solo Vendor")
|
||||
:db/id vendor-temp-id)])
|
||||
vendor-id (get tempids vendor-temp-id)]
|
||||
;; When: Attempt to merge vendor with itself
|
||||
;; Then: Exception is thrown with validation error
|
||||
(is (thrown-with-msg? clojure.lang.ExceptionInfo
|
||||
#"Please select two different vendors"
|
||||
(sut/merge-submit {:form-params {:source-vendor vendor-id
|
||||
:target-vendor vendor-id}
|
||||
:request-method :put
|
||||
:identity admin-identity})))))))
|
||||
|
||||
(deftest vendor-merge-invalid-vendor-handled
|
||||
(testing "Vendor merge should handle invalid vendor IDs gracefully"
|
||||
(let [admin-identity (admin-token)]
|
||||
;; Given: Create a target vendor
|
||||
(let [target-temp-id (str "vendor-target-" (rand-int 100000))
|
||||
tempids (setup-test-data [(assoc (create-vendor "Valid Target Vendor")
|
||||
:db/id target-temp-id)])
|
||||
target-vendor-id (get tempids target-temp-id)
|
||||
;; Invalid source vendor ID
|
||||
invalid-source-id 999999999]
|
||||
;; When: Attempt merge with invalid source
|
||||
(let [result (sut/merge-submit {:form-params {:source-vendor invalid-source-id
|
||||
:target-vendor target-vendor-id}
|
||||
: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
|
||||
(testing "Vendor hydration should include all required fields"
|
||||
;; Given: Create a comprehensive vendor
|
||||
(let [vendor-temp-id (str "vendor-complete-" (rand-int 100000))
|
||||
tempids (setup-test-data [(assoc (create-vendor "Complete Vendor"
|
||||
:vendor/print-as "CV Print Name"
|
||||
:vendor/hidden false
|
||||
:vendor/terms 30)
|
||||
:db/id vendor-temp-id)])
|
||||
db (dc/db conn)
|
||||
vendor-id (get tempids vendor-temp-id)]
|
||||
;; When: Fetch and hydrate the vendor
|
||||
(let [hydrated (sut/hydrate-results [vendor-id] db {})
|
||||
vendor (first hydrated)]
|
||||
;; Then: All fields are present
|
||||
(is (some? vendor))
|
||||
(is (= "Complete Vendor" (:vendor/name vendor)))
|
||||
(is (= "CV Print Name" (:vendor/print-as vendor)))
|
||||
(is (= false (:vendor/hidden vendor)))
|
||||
(is (= 30 (:vendor/terms vendor)))))))
|
||||
Reference in New Issue
Block a user