---
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`
