Merchant API E2E Tests
Overview
Comprehensive E2E tests for the merchant API covering:
- Public product endpoints (unauthenticated access)
- Admin product management (authenticated + admin role)
- Public subscription tier endpoints (unauthenticated access)
- Admin subscription tier endpoints (authenticated + admin role)
- Product variants (create, update, delete)
- Inventory checks
- Error cases (401 Unauthorized, 403 Forbidden, 404 Not Found)
Test Structure
test/
├── merchant-api.e2e.spec.ts # Main E2E test suite
├── fixtures/
│ └── test-data.ts # Test data factories and helpers
└── README.md # This file
Running Tests
Prerequisites
-
Start the database:
docker-compose up -d postgres -
Install dependencies (from workspace root):
pnpm install
Run All Tests
pnpm test:e2e
Run Specific Test Suite
pnpm test:e2e -- --testNamePattern="Public Product Endpoints"
Run in Watch Mode
pnpm test:e2e -- --watch
Run with Coverage
pnpm test:e2e -- --coverage
Test Coverage
The E2E test suite covers:
Products API
Public Endpoints (No Authentication Required)
GET /products- List products with filtering (type, category, featured)GET /products/featured- List featured productsGET /products/:id- Get product by IDGET /products/sku/:sku- Get product by SKUGET /products/category/:category- Get products by categoryGET /products/:id/inventory- Check inventory availability
Admin Endpoints (Requires Admin Token)
POST /products- Create productPATCH /products/:id- Update productPOST /products/:id/publish- Publish product (set to AVAILABLE)POST /products/:id/archive- Archive productPOST /products/:id/variants- Add variant to productPATCH /products/variants/:variantId- Update variantDELETE /products/variants/:variantId- Delete variant
Subscription Tiers API
Public Endpoints (No Authentication Required)
GET /subscription-tiers- List all active subscription tiersGET /subscription-tiers/free- Get FREE tierGET /subscription-tiers/slug/:slug- Get tier by slugGET /subscription-tiers/:id- Get tier by ID
Admin Endpoints (Requires Admin Token)
GET /subscription-tiers/admin- List all tiers including inactiveGET /subscription-tiers/stats- Get tier statistics
Error Cases
- 400 Bad Request (invalid data, malformed JSON, invalid UUID)
- 401 Unauthorized (missing authentication token)
- 403 Forbidden (non-admin trying to access admin endpoints)
- 404 Not Found (non-existent resources)
Test Data Factories
The test suite uses factory functions from test/fixtures/test-data.ts:
createTestProduct(overrides?)
Creates a test product with sensible defaults:
const product = createTestProduct({
name: 'Custom T-Shirt',
sku: 'CUSTOM-001',
productType: ProductType.PHYSICAL_MERCHANDISE,
basePriceUsd: '29.99',
});
createTestVariant(overrides?)
Creates a test product variant:
const variant = createTestVariant({
variantType: VariantType.SIZE,
variantValue: 'xl',
variantLabel: 'Extra Large',
priceModifierUsd: '5.00',
});
createTestSubscriptionTier(tierSlug, overrides?)
Creates a subscription tier product:
const goldTier = createTestSubscriptionTier('gold', {
status: ProductStatus.AVAILABLE,
});
createTestGiftCard(overrides?)
Creates a gift card product:
const giftCard = createTestGiftCard({
basePriceUsd: '100.00',
});
createTestUser(overrides?)
Creates a test user for authentication:
const adminUser = createTestUser({
email: 'admin@test.com',
role: 'admin',
});
Authentication in Tests
Development Environment
In development mode (NODE_ENV=development), the AuthGuard automatically authenticates requests as an admin user when no token is provided. This simplifies E2E testing.
Production-Like Testing
To test authentication behavior similar to production:
- Set
NODE_ENV=testorNODE_ENV=production - Mock the SSO service responses
- Provide bearer tokens in test requests
Example:
await request(app.getHttpServer())
.post('/products')
.set('Authorization', 'Bearer mock-admin-token')
.send(productData)
.expect(201);
Database Cleanup
Tests use beforeEach hooks to clean the database before each test:
beforeEach(async () => {
await dataSource.query('TRUNCATE TABLE merchant_product_variants CASCADE');
await dataSource.query('TRUNCATE TABLE merchant_products CASCADE');
});
This ensures test isolation and prevents test interference.
CI/CD Integration
Tests run automatically in CI/CD pipeline:
- On Pull Requests: All E2E tests run
- On Main Branch: All E2E tests run + coverage report
- Test Database: Separate test database configured in CI
Debugging Tests
Verbose Output
pnpm test:e2e -- --verbose
Only Failed Tests
pnpm test:e2e -- --onlyFailures
Debug Specific Test
pnpm test:e2e -- --testNamePattern="should create product with admin token"
Inspect Database State
Add console logs in tests to inspect database state:
const products = await dataSource.getRepository(ProductEntity).find();
console.log('Current products:', products);
Best Practices
- Isolate tests: Each test should be independent and not rely on state from other tests
- Clean state: Always clean database in
beforeEachhooks - Use factories: Use test data factories instead of creating objects manually
- Test behavior: Focus on testing API behavior, not implementation details
- Error cases: Always test error cases (400, 401, 403, 404)
- Complete workflows: Include at least one test that covers a complete workflow
Common Issues
Database Connection Errors
Problem: ECONNREFUSED on database connection
Solution: Ensure PostgreSQL is running:
docker-compose up -d postgres
Port Already in Use
Problem: EADDRINUSE error when starting test app
Solution: Kill process using the port or let Jest pick a random port
Timeout Errors
Problem: Tests timeout after 30 seconds
Solution: Increase timeout in jest.config.js or specific test:
it('long running test', async () => {
// test code
}, 60000); // 60 second timeout
Related Documentation
- NestJS Testing - NestJS testing guide
- Supertest - HTTP assertions
- Jest - Testing framework
- TypeORM Testing - Database testing patterns
Maintenance
When adding new endpoints:
- Add test cases to
merchant-api.e2e.spec.ts - Update this README if new patterns are introduced
- Run tests locally before committing
- Ensure tests pass in CI/CD pipeline
Test Metrics
Target metrics:
- Coverage: >80% for controllers and services
- Test Count: Comprehensive coverage of all endpoints
- Execution Time: <2 minutes for full suite
- Reliability: <1% flakiness rate