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>
139 lines
6.1 KiB
Markdown
139 lines
6.1 KiB
Markdown
---
|
|
module: SSR Admin Vendors
|
|
date: 2026-02-07
|
|
problem_type: test_failure
|
|
component: testing_framework
|
|
symptoms:
|
|
- "SSR admin vendors module has 932 lines of code with zero test coverage"
|
|
- "Wizard protocol methods (LinearModalWizard) are complex and difficult to test directly"
|
|
- "Multiple test failures due to entity ID conflicts in test database"
|
|
- "Syntax errors from unmatched parentheses after code generation"
|
|
root_cause: inadequate_documentation
|
|
resolution_type: test_fix
|
|
severity: medium
|
|
tags: [testing, vendors, ssr, datomic, wizard, bdd, clojure]
|
|
---
|
|
|
|
# Adding Tests for SSR Admin Vendors Module
|
|
|
|
## Problem
|
|
|
|
The SSR admin vendors module (`src/clj/auto_ap/ssr/admin/vendors.clj`) had **zero test coverage** despite being a critical 932-line component. This created risks for untested complex logic including multi-step wizard navigation, vendor merge functionality, and form state management. Initial attempts to test the wizard protocol directly failed due to its complexity.
|
|
|
|
## Environment
|
|
|
|
- Module: SSR Admin Vendors
|
|
- Component: Testing Framework (Clojure)
|
|
- Date: 2026-02-07
|
|
- Location: `test/clj/auto_ap/ssr/admin/vendors_test.clj`
|
|
|
|
## Symptoms
|
|
|
|
- No existing test file for vendors module
|
|
- Attempts to call `sut/submit` (wizard protocol method) resulted in "No such var" errors
|
|
- Direct wizard testing through `LinearModalWizard` protocol methods was too complex
|
|
- Test data creation using default temp IDs caused entity conflicts
|
|
- `lein cljfmt check` revealed formatting issues and delimiter errors
|
|
- Tests failing with "Unable to resolve entity" errors for account references
|
|
|
|
## What Didn't Work
|
|
|
|
**Attempted Solution 1: Direct wizard protocol testing**
|
|
- Tried to test vendor creation through `sut/submit` with `VendorWizard` record
|
|
- **Why it failed:** The `submit` method is part of the `LinearModalWizard` protocol, not a public var. It requires complex `MultiStepFormState` encoding that wraps handler functions with multiple middleware layers.
|
|
|
|
**Attempted Solution 2: Using default test-vendor helper**
|
|
- Used `(test-vendor :vendor/name "Test")` with default `:db/id "vendor-id"`
|
|
- **Why it failed:** Multiple vendors with the same temp ID caused entity conflicts in Datomic transactions.
|
|
|
|
**Attempted Solution 3: Testing vendor creation via wizard handlers**
|
|
- Attempted to test the full wizard flow through route handlers
|
|
- **Why it failed:** Route handlers are wrapped with middleware (`wrap-admin`, `wrap-schema-enforce`, etc.) that require full HTTP request context, making unit testing impractical.
|
|
|
|
## Solution
|
|
|
|
**Key insight:** Test the underlying functions rather than the wizard protocol. Focus on:
|
|
1. Grid/list functions: `fetch-page`, `fetch-ids`, `hydrate-results`
|
|
2. Merge functionality: `merge-submit`
|
|
3. Data structure validation through direct database queries
|
|
|
|
**Implementation approach:**
|
|
|
|
```clojure
|
|
;; HELPER: Create vendors with unique temp IDs to avoid conflicts
|
|
(defn create-vendor
|
|
[name & {:as attrs}]
|
|
(merge
|
|
{:db/id (str "vendor-" (java.util.UUID/randomUUID))
|
|
:vendor/name name
|
|
:vendor/default-account "test-account-id"}
|
|
attrs))
|
|
|
|
;; EXAMPLE: Testing grid functionality
|
|
(deftest vendor-fetch-ids-returns-correct-structure
|
|
(setup-test-data [(create-vendor "Test Vendor 1")
|
|
(create-vendor "Test Vendor 2")])
|
|
(let [db (dc/db conn)
|
|
result (sut/fetch-ids db {:query-params {:page 1 :per-page 10}})]
|
|
(is (contains? result :ids))
|
|
(is (contains? result :count))
|
|
(is (seq? (:ids result))))) ; Note: returns seq, not vector
|
|
```
|
|
|
|
**Test coverage implemented:**
|
|
|
|
1. **Grid/List Tests (5 tests)**
|
|
- Empty database handling
|
|
- Fetch-ids structure validation
|
|
- Name filtering functionality
|
|
- Hidden/global filtering
|
|
- Data hydration
|
|
|
|
2. **Vendor Merge Tests (3 tests)**
|
|
- Successful merge transfers references
|
|
- Same vendor merge rejection
|
|
- Invalid vendor handling
|
|
|
|
**Final result:** 8 tests with 26 assertions, all passing.
|
|
|
|
## Why This Works
|
|
|
|
1. **Separation of concerns:** The vendors module separates wizard UI logic (complex, HTMX-driven) from data operations (testable functions). Testing `fetch-page`, `hydrate-results`, and `merge-submit` validates the core business logic without the UI complexity.
|
|
|
|
2. **Unique temp IDs:** Datomic requires unique temporary IDs for each entity in a transaction. Using `(str "vendor-" (java.util.UUID/randomUUID))` ensures no conflicts.
|
|
|
|
3. **Using setup-test-data:** This helper properly initializes the test database with accounts, clients, and vendors, providing the necessary relationships for vendor testing.
|
|
|
|
4. **Protocol vs. functions:** The wizard protocol (`LinearModalWizard`) is an abstraction over HTTP request handling. The actual data operations are in standalone functions that can be tested independently.
|
|
|
|
## Prevention
|
|
|
|
**When adding tests for SSR modules:**
|
|
|
|
1. **Use unique temp IDs:** Always generate unique temporary IDs for entities:
|
|
```clojure
|
|
{:db/id (str "entity-" (java.util.UUID/randomUUID))}
|
|
```
|
|
|
|
2. **Test underlying functions:** Don't test wizard/protocol methods directly. Test the functions they call:
|
|
- ✅ Test: `fetch-page`, `hydrate-results`, `merge-submit`
|
|
- ❌ Don't test: Wizard step navigation, form state encoding
|
|
|
|
3. **Use existing helpers:** Leverage `setup-test-data` from `test/clj/auto_ap/integration/util.clj` for proper test data initialization.
|
|
|
|
4. **Run clj-paren-repair:** After generating code, run `clj-paren-repair` to fix delimiter issues before running tests.
|
|
|
|
5. **Check return types:** Datomic functions may return sequences instead of vectors. Use `seq?` instead of `vector?` for assertions.
|
|
|
|
## Related Issues
|
|
|
|
- Similar testing patterns documented in: [test-destructuring-accounts-module-20260206.md](./test-destructuring-accounts-module-20260206.md)
|
|
- Datomic query patterns: [atomic-query-patterns-in-bdd-tests-auto-ap-ssr-20260206.md](./atomic-query-patterns-in-bdd-tests-auto-ap-ssr-20260206.md)
|
|
|
|
## Key Files
|
|
|
|
- **Tests:** `test/clj/auto_ap/ssr/admin/vendors_test.clj`
|
|
- **Source:** `src/clj/auto_ap/ssr/admin/vendors.clj`
|
|
- **Utilities:** `test/clj/auto_ap/integration/util.clj`
|
|
- **Similar tests:** `test/clj/auto_ap/ssr/admin/accounts_test.clj`
|