- Add multi-signer contract creation with staff/customer selection
- Add signer-specific signing URLs (/sign/s/{token})
- Add sequential and parallel signing modes
- Fix can_sign check in frontend (use top-level response field)
- Fix required field validation to work for all template types
- Fix PDF overlay generation for HTML templates with generated PDFs
- Add signature pre-fill support in template field editor
- Add signature remember/re-apply feature during signing
- Update PDFOverlayService to read from contract.original_pdf_path
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
8.5 KiB
useTenantExists Hook - Test Suite Summary
Overview
Comprehensive test suite for the useTenantExists hook with 27 test cases covering all functionality, edge cases, and error scenarios.
Files Created
1. Test File
Location: /home/poduck/Desktop/smoothschedule2/frontend/src/hooks/__tests__/useTenantExists.test.ts
- Lines of code: 533
- Test cases: 27
- Test groups: 9 describe blocks
- Technologies: Vitest, React Testing Library, MSW
2. Configuration Files
Vitest Config: /home/poduck/Desktop/smoothschedule2/frontend/vitest.config.ts
- Configures test environment (jsdom)
- Sets up test coverage reporting
- Configures path aliases
Test Setup: /home/poduck/Desktop/smoothschedule2/frontend/src/test/setup.ts
- Mocks window.matchMedia
- Mocks localStorage
- Mocks location for subdomain testing
- Sets up cleanup and globals
3. Documentation
- SETUP_TESTING.md - Quick setup guide for running tests
- TESTING.md - Comprehensive testing guide with best practices
- install-test-deps.sh - Automated dependency installation script
Test Coverage
✓ All Required Test Cases Covered
- Returns exists: true when API returns 200 ✓
- Returns exists: false when API returns 404 ✓
- Returns exists: false when subdomain is null ✓
- Returns exists: false on other API errors ✓
- Shows loading state while fetching ✓
- Caches results (staleTime) ✓
- Does not make API call when subdomain is null (enabled: false) ✓
Additional Test Coverage
API Success Cases (2 tests)
- Returns exists: true when API returns 200
- Includes subdomain in query params and headers
API Error Cases (4 tests)
- Returns exists: false when API returns 404
- Returns exists: false on 500 server error
- Returns exists: false on network error
- Returns exists: false on 403 forbidden error
Null Subdomain Cases (3 tests)
- Returns exists: false when subdomain is null
- Does not make API call when subdomain is null
- Returns exists: false when subdomain is empty string
Loading States (2 tests)
- Shows loading state while fetching
- Transitions from loading to loaded correctly
Caching Behavior (2 tests)
- Caches results with 5 minute staleTime
- Makes separate requests for different subdomains
Query Key Behavior (1 test)
- Uses correct query key with subdomain
Edge Cases (3 tests)
- Handles subdomain with special characters
- Handles very long subdomain
- Handles concurrent requests for same subdomain
Query Retry Behavior (2 tests)
- Does not retry on 404
- Does not retry on other errors
Test Structure
MSW API Mocking
The tests use Mock Service Worker (MSW) to intercept API calls:
server.use(
rest.get(`${API_BASE_URL}/business/public-info/`, (req, res, ctx) => {
const subdomain = req.url.searchParams.get('subdomain');
if (subdomain === 'testbusiness') {
return res(ctx.status(200), ctx.json({
id: 1,
name: 'Test Business',
subdomain: 'testbusiness',
}));
}
return res(ctx.status(404));
})
);
React Query Wrapper
Tests use a custom wrapper to provide QueryClient context:
const createWrapper = () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
gcTime: 0,
},
},
});
return ({ children }) => (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
);
};
Test Pattern
Each test follows the Arrange-Act-Assert pattern:
it('returns exists: true when API returns 200', async () => {
// Arrange - Setup mock
server.use(/* ... */);
// Act - Render hook
const { result } = renderHook(() => useTenantExists('testbusiness'), {
wrapper: createWrapper(),
});
// Wait for loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Assert - Verify results
expect(result.current.exists).toBe(true);
expect(result.current.error).toBe(null);
});
Setup Instructions
Quick Setup (3 steps)
-
Install dependencies:
cd /home/poduck/Desktop/smoothschedule2/frontend ./install-test-deps.sh -
Update package.json: Add these scripts:
{ "scripts": { "test": "vitest", "test:ui": "vitest --ui", "test:run": "vitest run", "test:coverage": "vitest run --coverage" } } -
Run tests:
npm run test
Manual Installation
npm install -D \
vitest@1.0.4 \
@vitest/ui@1.0.4 \
jsdom@23.0.1 \
@testing-library/react@14.1.2 \
@testing-library/jest-dom@6.1.5 \
@testing-library/user-event@14.5.1 \
msw@2.0.11 \
@types/jsdom@21.1.6
Running Tests
All Tests
npm run test
Specific Hook Tests
npm run test -- useTenantExists
With UI
npm run test:ui
With Coverage
npm run test:coverage
Watch Mode
npm run test -- --watch
Expected Test Results
When all tests pass, you should see:
✓ src/hooks/__tests__/useTenantExists.test.ts (27)
✓ useTenantExists (27)
✓ API Success Cases (2)
✓ returns exists: true when API returns 200
✓ includes subdomain in query params and headers
✓ API Error Cases (4)
✓ returns exists: false when API returns 404
✓ returns exists: false on 500 server error
✓ returns exists: false on network error
✓ returns exists: false on 403 forbidden error
✓ Null Subdomain Cases (3)
✓ returns exists: false when subdomain is null
✓ does not make API call when subdomain is null
✓ returns exists: false when subdomain is empty string
✓ Loading States (2)
✓ shows loading state while fetching
✓ transitions from loading to loaded correctly
✓ Caching Behavior (2)
✓ caches results with 5 minute staleTime
✓ makes separate requests for different subdomains
✓ Query Key Behavior (1)
✓ uses correct query key with subdomain
✓ Edge Cases (3)
✓ handles subdomain with special characters
✓ handles very long subdomain
✓ handles concurrent requests for same subdomain
✓ Query Retry Behavior (2)
✓ does not retry on 404
✓ does not retry on other errors
Test Files 1 passed (1)
Tests 27 passed (27)
Test Coverage Goals
- Lines: > 90%
- Functions: > 90%
- Branches: > 85%
The comprehensive test suite should achieve high coverage for the useTenantExists hook.
Hook Under Test
File: /home/poduck/Desktop/smoothschedule2/frontend/src/hooks/useTenantExists.ts
Functionality:
- Takes a subdomain string or null
- Makes API call to
/business/public-info/with subdomain param - Returns
{ exists: boolean, isLoading: boolean, error: Error | null } - Returns
exists: trueif business found (200 response) - Returns
exists: falseif business not found (404 response) - Uses React Query with 5 minute staleTime
- Does not make API call when subdomain is null (enabled: false)
- Does not retry on errors (retry: false)
Verification Checklist
Before running tests, verify:
- Dependencies installed (
npm list vitestshould show version) - Configuration files in place (vitest.config.ts, src/test/setup.ts)
- Test file created at correct location
- package.json scripts updated
- Backend API running (if testing against real API)
Troubleshooting
Tests fail with "Cannot find module"
- Run
npm installto ensure dependencies are installed - Check that vitest is in devDependencies
MSW errors
- Ensure MSW version 2.x is installed:
npm install -D msw@2.0.11 - Check that server is properly setup in tests
React Query errors
- Verify wrapper is providing QueryClient to hooks
- Check that QueryClient is configured with
retry: falsefor tests
API URL mismatch
- Update
API_BASE_URLconstant in test file if your API runs on different port
Next Steps
- Install dependencies
- Run tests
- Review coverage report
- Add more tests for other hooks following this pattern
- Integrate into CI/CD pipeline
Resources
Created: 2025-12-04 Test Suite Version: 1.0 Status: Ready for execution