Files
integreat/docs/plans/2026-02-06-feat-add-tests-for-ssr-admin-vendors-plan.md
Bryce a7daf839ec 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>
2026-02-06 23:53:31 -08:00

17 KiB

title, type, date, component, tags
title type date component tags
Add comprehensive tests for SSR admin vendors module feat 2026-02-06 auto-ap.ssr.admin.vendors
testing
ssr
vendors
wizard
bdd

Add Comprehensive Tests for SSR Admin Vendors Module

Overview

Add comprehensive BDD-style tests for the SSR admin vendors module (src/clj/auto_ap/ssr/admin/vendors.clj). The vendors module is a complex multi-step wizard implementation with 5 wizard steps (Info, Terms, Account, Address, Legal) and requires more extensive testing than the accounts module due to its complex form state management, vendor merge functionality, and nested override grids.

Problem Statement

The vendors module currently has zero tests despite being a critical admin functionality with 932 lines of code. This creates risks:

  1. Untested complex logic: Multi-step wizard navigation, form state management, and validation
  2. No safety net for refactors: Vendor merge, grid overrides, and dynamic fields are complex
  3. No documentation of expected behavior: Tests serve as executable documentation
  4. Risk of regression: Without tests, bugs in vendor creation/management could go unnoticed

Proposed Solution

Create a comprehensive test suite at test/clj/auto_ap/ssr/admin/vendors_test.clj following the established patterns from accounts_test.clj, but with additional complexity for:

  • Wizard navigation testing: Testing step transitions, validation at each step
  • Vendor merge functionality: Testing source/target vendor selection and entity merging
  • Override grids: Testing terms overrides and account overrides with client-specific data
  • Complex form state: Testing MultiStepFormState encoding/decoding
  • Nested entity handling: Testing vendor address, legal entity info, primary contact

Technical Considerations

Architecture Impact

  • Tests will mirror the accounts test structure: test/clj/auto_ap/ssr/admin/vendors_test.clj
  • Will require understanding of LinearModalWizard protocol and MultiStepFormState
  • Tests will use same utilities: wrap-setup, admin-token, setup-test-data
  • Will need to mock Solr indexing like accounts tests do

Performance Implications

  • In-memory Datomic with test fixtures for isolation
  • Each test should be independent with proper setup/teardown
  • Estimated 15-20 tests (vs 9 for accounts) due to complexity

Security Considerations

  • Admin-only access verification
  • Non-admin access should be rejected
  • JWT validation for vendor operations

Testing Challenges

  1. MultiStepFormState encoding: The wizard uses complex form state encoding via wrap-decode-multi-form-state
  2. Step-specific validation: Each wizard step validates only its subset of the schema
  3. Dynamic client-dependent fields: Account typeahead depends on client selection
  4. Grid row management: Adding/removing terms and account override rows

Acceptance Criteria

Functional Requirements

Grid & List View Tests (4 tests) - IMPLEMENTED

  • Test 1: Vendor grid page loads and displays vendors

    • Given: Test vendors exist in database
    • When: Admin navigates to vendors page
    • Then: Vendor table displays with correct columns (name, email, default account)
    • Then: Usage badges show correct client counts and totals
    • Implemented as: vendor-fetch-page-returns-vendors
  • Test 2: Vendor grid filtering by name works

    • Given: Multiple vendors exist with different names
    • When: Admin filters by name "Acme"
    • Then: Only vendors matching "Acme" are displayed
    • Then: Matching count reflects filtered results
    • Implemented as: vendor-fetch-ids-with-name-filter
  • Test 3: Vendor grid filtering by type (hidden/global) works

    • Given: Hidden and global vendors exist
    • When: Admin selects "Only hidden" filter
    • Then: Only hidden vendors are displayed
    • When: Admin selects "Only global" filter
    • Then: Only non-hidden vendors are displayed
    • Implemented as: vendor-fetch-ids-with-hidden-filter
  • Test 4: Vendor grid handles empty database

    • Given: No vendors in database
    • When: Admin navigates to vendors page
    • Then: Returns empty results without errors
    • Implemented as: vendor-grid-loads-with-empty-database
    • Note: Sorting tests deferred due to vendor module sorting configuration

Vendor Creation Tests - Info Step (2 tests)

  • Test 5: Admin successfully creates vendor with basic info

    • Given: Admin is logged in with valid token
    • When: Admin submits vendor info form (name, hidden flag)
    • Then: Vendor is created successfully
    • Then: Vendor appears in database
    • Then: Vendor is indexed in Solr
  • Test 6: Vendor creation validation - empty name rejected

    • Given: Admin submits form without vendor name
    • When: Validation runs on info step
    • Then: Validation error for name field
    • Then: No vendor is created

Vendor Creation Tests - Terms Step (3 tests)

  • Test 7: Vendor can have default terms set

    • Given: Admin on terms step of wizard
    • When: Admin sets terms to 30 days
    • Then: Terms are saved with vendor
    • Then: Terms appear in database
  • Test 8: Vendor terms override grid works

    • Given: Admin on terms step with client overrides
    • When: Admin adds terms override for specific client (45 days)
    • Then: Override is saved
    • When: Override is removed
    • Then: Override is deleted from database
  • Test 9: Automatic payment flag per client works

    • Given: Admin on terms step
    • When: Admin marks vendor for automatic payment for a client
    • Then: Flag is saved in database

Vendor Creation Tests - Account Step (3 tests)

  • Test 10: Vendor default account selection works

    • Given: Admin on account step
    • When: Admin selects default account from typeahead
    • Then: Default account association is saved
  • Test 11: Vendor account override grid works

    • Given: Admin on account step with client-specific accounts
    • When: Admin adds account override for client (different default account)
    • Then: Override is saved in database
    • When: Client is changed, account typeahead refreshes
    • Then: New client-specific accounts are available
  • Test 12: Account typeahead filters by client

    • Given: Client A and Client B have different accounts
    • When: Admin selects Client A in override row
    • Then: Only Client A's accounts appear in typeahead

Vendor Creation Tests - Address Step (2 tests)

  • Test 13: Vendor address information is saved

    • Given: Admin on address step
    • When: Admin enters complete address (street, city, state, zip)
    • Then: Address entity is created and linked to vendor
    • Then: All address fields are persisted correctly
  • Test 14: Partial address is handled correctly

    • Given: Admin enters only street address
    • When: Vendor is saved
    • Then: Address entity is created with available fields
    • Then: Missing fields remain empty
  • Test 15: Vendor legal entity (business) information is saved

    • Given: Admin on legal step
    • When: Admin enters legal entity name and TIN (EIN)
    • Then: Legal entity info is saved
    • Then: 1099 type is stored correctly
  • Test 16: Vendor individual legal entity is saved

    • Given: Admin on legal step
    • When: Admin enters individual name (first, middle, last) and SSN
    • Then: Individual legal entity info is saved
    • Then: TIN type is set to SSN
  • Test 17: Legal entity validation works

    • Given: Admin enters invalid TIN format
    • When: Validation runs
    • Then: Appropriate validation error is shown

Vendor Update Tests (2 tests)

  • Test 18: Existing vendor can be updated

    • Given: Vendor exists in database
    • When: Admin edits and saves vendor
    • Then: Changes are persisted
    • Then: Solr index is updated
    • Then: Grid row reflects changes
  • Test 19: Vendor update maintains existing overrides

    • Given: Vendor has terms and account overrides
    • When: Admin updates vendor name
    • Then: Overrides remain intact

Vendor Merge Tests (3 tests) - IMPLEMENTED

  • Test 20: Vendor merge transfers all references

    • Given: Source vendor has invoices/bills, target vendor exists
    • When: Admin merges source into target
    • Then: All references to source are updated to target
    • Then: Source vendor is deleted
    • Then: Success notification is shown
    • Implemented as: vendor-merge-transfers-references
  • Test 21: Same vendor merge is rejected

    • Given: Admin selects same vendor for source and target
    • When: Merge is attempted
    • Then: Validation error: "Please select two different vendors"
    • Implemented as: vendor-merge-same-vendor-rejected
  • Test 22: Non-existent vendor merge is handled

    • Given: Invalid vendor ID for source
    • When: Merge is attempted
    • Then: Appropriate error is shown
    • Implemented as: vendor-merge-invalid-vendor-handled

Security Tests (2 tests)

  • Test 23: Non-admin cannot create vendor

    • Given: Non-admin user token
    • When: User attempts to create vendor
    • Then: Request is rejected (403 Forbidden)
  • Test 24: Non-admin cannot merge vendors

    • Given: Non-admin user token
    • When: User attempts to merge vendors
    • Then: Request is rejected

Non-Functional Requirements

  • Tests use wrap-setup fixture for database isolation
  • Tests use admin-token utility for authentication
  • Solr is mocked using with-redefs with InMemSolrClient
  • Test execution time < 3 seconds per test
  • All tests pass with lein test auto-ap.ssr.admin.vendors-test

Quality Gates

  • 24 tests implemented and passing
  • Test coverage > 75% for vendor handlers
  • Code formatted with lein cljfmt check
  • No debug statements (println, alog/peek) in tests
  • All deftest blocks at column 0 (consistent structure)

Implementation Plan

Phase 1: Foundation (2 hours)

Tasks:

  1. Review vendors module structure

    • Read src/clj/auto_ap/ssr/admin/vendors.clj
    • Identify key functions: fetch-ids, hydrate-results, fetch-page
    • Identify wizard steps: Info, Terms, Account, Address, Legal
    • Identify merge functionality
  2. Review accounts test as reference

    • Read test/clj/auto_ap/ssr/admin/accounts_test.clj
    • Copy test structure and utilities
    • Note ffirst pattern for Datomic queries
    • Note [:db/ident] for entity references
  3. Create test file structure

    • Create test/clj/auto_ap/ssr/admin/vendors_test.clj
    • Set up namespace with required imports
    • Add wrap-setup fixture

Deliverable: Test file created with proper structure, ready for test implementation

Phase 2: Grid/List Tests (1.5 hours)

  1. Implement Test 1: Vendor grid loads
  2. Implement Test 2: Name filtering
  3. Implement Test 3: Type filtering (hidden/global)
  4. Implement Test 4: Sorting

Deliverable: 4 grid tests passing

Phase 3: Vendor Creation - Info & Terms (2.5 hours)

  1. Implement Test 5: Create vendor with basic info
  2. Implement Test 6: Name validation
  3. Implement Test 7: Default terms
  4. Implement Test 8: Terms override grid
  5. Implement Test 9: Automatic payment flag

Deliverable: 5 vendor creation tests (info + terms) passing

Phase 4: Vendor Creation - Account & Address (2.5 hours)

  1. Implement Test 10: Default account selection
  2. Implement Test 11: Account override grid
  3. Implement Test 12: Client-filtered account typeahead
  4. Implement Test 13: Complete address
  5. Implement Test 14: Partial address

Deliverable: 5 vendor creation tests (account + address) passing

  1. Implement Test 15: Legal entity (business)
  2. Implement Test 16: Legal entity (individual)
  3. Implement Test 17: Legal entity validation
  4. Implement Test 18: Vendor update
  5. Implement Test 19: Update maintains overrides

Deliverable: 5 tests (legal + update) passing

Phase 6: Vendor Merge & Security (2 hours)

  1. Implement Test 20: Merge transfers references
  2. Implement Test 21: Same vendor merge rejected
  3. Implement Test 22: Invalid vendor merge handled
  4. Implement Test 23: Non-admin cannot create
  5. Implement Test 24: Non-admin cannot merge

Deliverable: 5 tests (merge + security) passing

Phase 7: Refinement & Quality (1 hour)

  1. Run lein cljfmt check and fix issues
  2. Run full test suite
  3. Review for debug statements and remove
  4. Verify consistent test structure (deftest at column 0)
  5. Add test documentation comments

Deliverable: All 24 tests passing, code formatted, no debug code

Success Metrics

  • 24 BDD test scenarios implemented and passing
  • Test file follows project conventions
  • Code formatted with lein cljfmt check
  • All tests use proper Datomic query patterns (ffirst, [:db/ident])
  • Solr mocking works correctly
  • Tests run in < 60 seconds for full suite
  • No regression in existing functionality

Dependencies & Risks

Prerequisites

  • src/clj/auto_ap/ssr/admin/vendors.clj (exists)
  • test/clj/auto_ap/integration/util.clj (test utilities)
  • Existing accounts tests as reference pattern
  • Datomic database schema for vendors

Potential Risks

  1. Complexity Risk: MultiStepFormState encoding/decoding is complex

    • Mitigation: Reference accounts test patterns, test incrementally
  2. Time Risk: 24 tests may take longer than estimated

    • Mitigation: Prioritize core tests (creation, merge), add edge cases later
  3. Wizard State Risk: Wizard step navigation testing is novel

    • Mitigation: Start with simple tests, incrementally add complexity
  4. Grid Testing Risk: Override grid testing is complex

    • Mitigation: Test basic CRUD operations first, then edge cases

References & Research

Internal References

Vendor Source Code:

  • src/clj/auto_ap/ssr/admin/vendors.clj - Main implementation (932 lines)
    • fetch-ids - Query builder for vendor grid
    • hydrate-results - Data hydration for grid display
    • fetch-page - Grid pagination
    • grid-page - Grid configuration
    • merge-submit - Vendor merge logic
    • 5 Wizard step records: InfoModal, TermsModal, AccountModal, AddressModal, LegalEntityModal
    • VendorWizard record implementing LinearModalWizard protocol

Wizard Framework:

  • src/clj/auto_ap/ssr/components/multi_modal.clj - LinearModalWizard protocol
    • ModalWizardStep protocol methods: step-key, edit-path, render-step, step-schema, step-name
    • LinearModalWizard protocol methods: navigate, get-current-step, render-wizard, submit
    • Handler wrappers: wrap-wizard, wrap-init-multi-form-state, wrap-decode-multi-form-state

Test Utilities:

  • test/clj/auto_ap/integration/util.clj - Test helpers
    • wrap-setup - Test database setup/teardown
    • admin-token - Admin authentication
    • setup-test-data - Test data creation
    • test-vendor - Vendor test data helper

Reference Tests:

  • test/clj/auto_ap/ssr/admin/accounts_test.clj - Accounts test pattern (151 lines)
  • test/clj/auto_ap/integration/graphql/vendors.clj - GraphQL vendor tests (79 lines)

Learnings:

  • docs/solutions/test-failures/atomic-query-patterns-in-bdd-tests-auto-ap-ssr-20260206.md - Datomic query patterns (ffirst, [:db/ident])
  • docs/solutions/test-failures/debug-statement-and-test-nesting-fix-accounts-20260206.md - Test quality issues to avoid

Testing Patterns

Datomic Query Pattern:

; Use ffirst to extract entity ID from tuple
(let [results (dc/q '[:find ?e :where [?e :vendor/name "Acme"]] db)
      vendor-id (ffirst results)]  ; Not (first results)
  ...)

Entity Reference Resolution:

; Include [:db/ident] to resolve enum values
(let [vendor (dc/pull db
                      '[:vendor/name
                        {[:vendor/legal-entity-tin-type :xform iol-ion.query/ident] [:db/ident]}]
                      vendor-id)]
  ; Access as: (:db/ident (:vendor/legal-entity-tin-type vendor))
  ...)

Solr Mocking Pattern:

(with-redefs [auto-ap.solr/impl (auto-ap.solr/->InMemSolrClient (atom {}))]
  ; Test code here
  )

Test Structure Pattern:

(deftest vendor-creation-success
  (testing "Admin should be able to create a new vendor"
    (with-redefs [auto-ap.solr/impl (auto-ap.solr/->InMemSolrClient (atom {}))]
      (let [admin-identity (admin-token)
            ; Test implementation
            ]))))

AI-Era Considerations

When implementing with AI assistance:

  1. Accelerated test generation: AI can generate test scaffolding quickly
  2. Pattern recognition: Use existing accounts tests as templates
  3. Datomic patterns: Ensure AI applies ffirst and [:db/ident] correctly
  4. Human review: All AI-generated tests should be reviewed for:
    • Correct assertion logic
    • Proper database verification
    • No debug statements left in
    • Consistent test structure

Next Steps

  1. Review Plan: Confirm scope and complexity level
  2. Start Implementation: Begin with Phase 1 (Foundation)
  3. Iterative Testing: Implement tests incrementally, verify each phase
  4. Code Review: Get feedback on test patterns
  5. Integration: Ensure tests pass with full test suite

Created: 2026-02-06
Priority: High (critical admin functionality untested)
Estimated Effort: 13 hours (across 7 phases)