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>
8.4 KiB
module, date, problem_type, component, symptoms, root_cause, severity, tags
| module | date | problem_type | component | symptoms | root_cause | severity | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| accounts test module | 2026-02-06 | test_failure | clojure_test |
|
incorrect_destructuring_patterns_and_parameter_formats | medium |
|
Test Destructuring Issues in Accounts Module
Problem Description
Multiple tests in test/clj/auto_ap/ssr/admin/accounts_test.clj were failing due to incorrect destructuring patterns and parameter formats. Tests expected different return values and parameter structures than what the source code actually provides.
Observable Symptoms
FAIL in (account-creation-duplicate-numeric-code-detection)
expected: (contains? (:form-errors data) [:account/numeric-code])
actual: (not (contains? #:account{:numeric-code ["The code 12347 is already in use."]} [:account/numeric-code]))
FAIL in (account-grid-view-loads-accounts)
expected: (number? matching-count)
actual: (not (number? nil))
ERROR in (account-sorting-by-name)
Query is referencing unbound variables: #{?sort-}
Investigation Attempts
- Initial approach: Ran tests one at a time using
lein test :only auto-ap.ssr.admin.accounts-test/[test-name] - Discovered patterns: Found 3 distinct root causes affecting different test groups
- Checked source code: Reviewed
accounts.cljto understand actual function signatures and parameter expectations
What didn't work:
- Initially tried generic exception catching
- Attempted to modify source code (wrong approach - should only fix tests)
Root Cause Analysis
Issue 1: Form Errors Key Format (account-creation-duplicate-numeric-code-detection)
Problem: Test expected vector key [:account/numeric-code]but actual form-errors map uses keyword key:account/numeric-code`.
Technical explanation: The field-validation-error function creates form-errors as (assoc-in {} path [m]) where path is [:account/numeric-code]. This creates a map with keyword key, not vector key.
Code location: src/clj/auto_ap/ssr/utils.clj - field-validation-error function creates the structure.
Issue 2: fetch-page Return Value Format (grid view and display tests)
Problem: Test destructured fetch-page result into 3-tuple [_ accounts matching-count] but function actually returns 2-tuple [accounts matching-count].
Technical explanation: The fetch-page function returns [results matching-count] where:
- First element: array of account entities
- Second element: total count (number)
Code location: src/clj/auto_ap/ssr/admin/accounts.clj line 143-148:
(defn fetch-page [request]
(let [db (dc/db conn)
{ids-to-retrieve :ids matching-count :count} (fetch-ids db request)]
[(->> (hydrate-results ids-to-retrieve db request))
matching-count]))
Issue 3: Sort Parameter Format (sorting tests)
Problem: Tests passed sort as string :sort "name" but add-sorter-fields expects collection of sort-keys.
Technical explanation: The add-sorter-fields function iterates over (:sort args) which should be a collection like [{:sort-key "name"}]. When passing a string, it fails to iterate properly.
Code location: src/clj/auto_ap/ssr/admin/accounts.clj line 100-106:
(:sort query-params) (add-sorter-fields {"name" ['[?e :account/name ?n]
'[(clojure.string/upper-case ?n) ?sort-name]]
"code" ['[(get-else $ ?e :account/numeric-code 0) ?sort-code]]
"type" ['[?e :account/type ?t]
'[?t :db/ident ?ti]
'[(name ?ti) ?sort-type]]}
query-params)
Working Solution
Fix 1: Form Errors Key Format
Changed in test/clj/auto_ap/ssr/admin/accounts_test.clj line 57:
;; BEFORE
(is (contains? (:form-errors data) [:account/numeric-code]))
;; AFTER
(is (contains? (:form-errors data) :account/numeric-code))
Fix 2: fetch-page Destructuring Pattern
Changed in test/clj/auto_ap/ssr/admin/accounts_test.clj lines 98-104 and 110-117:
;; BEFORE - expecting 3-tuple
(let [result (sut/fetch-page {:query-params {:page 1 :per-page 10}})
[_ accounts matching-count] result]
(is (vector? result))
(is (= 2 (count result)))
(is (number? matching-count)))
;; AFTER - proper 2-tuple destructuring
(let [[accounts matching-count] (sut/fetch-page {:query-params {:page 1 :per-page 10}})]
(is (number? matching-count)))
Fix 3: Sort Parameter Format
Changed in test/clj/auto_ap/ssr/admin/accounts_test.clj lines 126 and 150:
;; BEFORE - passing string
{:query-params {:page 1 :per-page 10 :sort "name"}}
;; AFTER - passing collection with sort-keys
{:query-params {:page 1 :per-page 10 :sort [{:sort-key "name"}]}}
Files Modified
test/clj/auto_ap/ssr/admin/accounts_test.clj: Fixed 4 test functionsaccount-creation-duplicate-numeric-code-detectionaccount-grid-view-loads-accountsaccount-grid-displays-correct-columnsaccount-sorting-by-nameaccount-sorting-by-type
Verification
Test results after fix:
Ran 9 tests containing 19 assertions.
0 failures, 0 errors.
All tests pass successfully.
Prevention Strategies
Destructuring Rules
-
Always inspect function signatures before writing tests
- Use
(-> (sut/fetch-page ...) meta)or read source code to understand return types - Verify tuple lengths before destructuring
- Use
-
Form errors follow a pattern
- Look at how
field-validation-errorcreates errors inutils.clj - Form errors use keyword keys, not vector keys
- Pattern:
(assoc-in {} path [message])where path is keyword(s)
- Look at how
-
Query parameters have specific formats
- Sort parameters should be collections:
[{:sort-key "field"}] - Check
add-sorter-fieldsimplementation in the source module - Don't assume single-value parameters when API accepts collections
- Sort parameters should be collections:
Test-First Approach
-
Mock/stub external dependencies in tests before calling functions
- Always use
with-redefsto control solr, database, etc. - This makes testing more predictable and isolated
- Always use
-
Run tests incrementally
- Fix one test at a time using
lein test :only - Track which tests fail to understand pattern
- Don't fix multiple unrelated issues simultaneously
- Fix one test at a time using
Pattern Recognition
Common destructuring issues to watch for:
| Component | Expected Format | Common Mistake | Fix |
|---|---|---|---|
fetch-page |
[results matching-count] |
3-tuple like [data pages total] |
Verify tuple length |
| Form errors | {:field-name message} |
[:field-name message] |
Use keyword keys |
| Sort params | [{:sort-key "field"}] |
"field" |
Use collection |
| Pagination | {:page 1 :per-page 10} |
{:page 1} |
Provide all needed params |
Cross-References
None - no similar issues found in existing documentation.
Lessons Learned
Key Patterns Extracted
- Never assume tuple sizes - Always verify return values match expectations
- Form error structure is consistent - Keyword keys, not vector keys
- Query parameter formats matter - Collections vs single values
- Inspect source code - The
add-sorter-fieldsfunction reveals the expected sort parameter format - Test incrementally - Run one test at a time to isolate issues
Debugging Process
When tests fail with "wrong number of arguments" or "destructuring failed":
- Check function signature in source code
- Add logging or print the actual return value
(println "Result:" result) - Verify parameter formats - especially collections
- Test incrementally - one failing test at a time
Documentation Reminder
Always document the actual API signature, not assumed ones:
;; BAD - assuming knowledge
(defn fetch-page [request] ...) ; assumed return type
;; GOOD - verified from source
;; From accounts.clj:143-148
;; Returns: [results matching-count] where results is array of entities
(defn fetch-page [request] ...)