Testing Your Integration
This guide covers testing strategies, test data patterns, and validation approaches for your MLA Service integration.
Testing Environments
Sandbox Environment
Use the sandbox environment for all testing:
| Property | Value |
|---|---|
| URL | https://leads-sandbox.alleviate.com/graphql |
| Lead Source | {partner}-sandbox |
| Mode | TEST |
| Rate Limit | 100 requests/minute |
Test Scenarios
1. Basic Lead Submission
Test the complete lead submission flow:
- Submit a lead with all required fields
- Verify you receive
idand a completedresultCode - Optionally query
getLeadStatusby ID for reconciliation - Verify result code handling in your integration
- If qualified (1013-1017), call
submitLead - Verify CRM submission success
describe('Lead Submission Flow', () => { it('should submit lead and receive final status', async () => { const result = await createLead(validLeadData); expect(result.id).toBeDefined(); expect([1000, 1001]).not.toContain(result.resultCode); });});2. Duplicate Detection
Test that duplicate leads are properly detected:
describe('Duplicate Detection', () => { it('should detect duplicate leads', async () => { const leadData = generateLeadData();
// Submit first lead const first = await createLead(leadData); expect(first.id).toBeDefined();
// Submit duplicate (same email/phone) const second = await createLead(leadData); const status = await getLeadStatus(second.id);
expect(status.resultCode).toBe(1003); // DUPLICATE_LEAD });});3. Validation Errors
Test that invalid input is properly rejected:
describe('Validation', () => { const invalidCases = [ { name: 'missing firstName', data: { ...validLead, firstName: undefined }, expectedError: 'firstName is required' }, { name: 'invalid email', data: { ...validLead, email: 'not-an-email' }, expectedError: 'Invalid email format' }, { name: 'invalid date format', data: { ...validLead, dateOfBirth: '06/15/1985' }, expectedError: 'Invalid date format' }, { name: 'invalid state', data: { ...validLead, state: 'XX' }, expectedError: 'Invalid state code' } ];
invalidCases.forEach(({ name, data, expectedError }) => { it(`should reject ${name}`, async () => { const result = await createLead(data); expect(result.errors).toBeDefined(); expect(result.errors[0].message).toContain(expectedError); }); });});4. Authentication Errors
Test authentication error handling:
describe('Authentication', () => { it('should reject expired token', async () => { const expiredToken = 'expired-token';
const result = await createLead(validLead, expiredToken);
expect(result.status).toBe(401); });
it('should refresh token on 401', async () => { // Implement token refresh logic test const result = await withTokenRefresh(() => createLead(validLead));
expect(result.id).toBeDefined(); });});5. Rate Limiting
Test rate limit handling:
describe('Rate Limiting', () => { it('should handle rate limits gracefully', async () => { const promises = [];
// Submit many leads quickly for (let i = 0; i < 150; i++) { promises.push(createLead(generateLeadData())); }
const results = await Promise.allSettled(promises);
// Some should succeed, some may be rate limited const rateLimited = results.filter( r => r.status === 'rejected' && r.reason.status === 429 );
// Verify retry logic handles rate limits expect(rateLimited.length).toBeGreaterThanOrEqual(0); });});6. Timeout Handling
Test long-running request scenarios:
describe('Timeout Handling', () => { it('should handle createLead timeout gracefully', async () => { await expect(createLead(slowLeadData)).rejects.toThrow('timeout'); });});Test Data Patterns
Valid Lead Data
const validLeadData = { firstName: 'Test', lastName: 'User', dateOfBirth: '1985-06-15', email: `test-${Date.now()}@example.com`, // Unique email homePhone: `949${Math.floor(Math.random() * 10000000).toString().padStart(7, '0')}`, address1: '123 Test Street', city: 'Los Angeles', state: 'CA', zipCode: '90001', socialSecurityNumber: '123456789', grossAnnualIncome: 75000, affiliateAppID: 'your-affiliate-id', leadId: 'test-lead-001'};// Note: leadSourceId and productCodes are configured server-side based on your credentialsLead Data Generator
function generateLeadData(overrides = {}) { const timestamp = Date.now();
return { firstName: 'Test', lastName: `User${timestamp}`, dateOfBirth: '1985-06-15', email: `test-${timestamp}@example.com`, homePhone: `949${timestamp.toString().slice(-7)}`, address1: '123 Test Street', city: 'Los Angeles', state: 'CA', zipCode: '90001', socialSecurityNumber: '123456789', affiliateAppID: 'your-affiliate-id', leadId: `test-${timestamp}`, ...overrides };}Mocking the API
Mock Server Setup
For unit tests, mock the GraphQL endpoint:
export const createLead = jest.fn().mockResolvedValue({ data: { createLead: { id: 'mock-uuid', resultCode: 1000, note: 'Lead submitted and processing' } }});
export const getLeadStatus = jest.fn() .mockResolvedValueOnce({ data: { getLeadStatus: { id: 'mock-uuid', resultCode: 1015, bidValue: '$15.00' } } });import { graphql } from 'msw';
export const handlers = [ graphql.mutation('CreateLead', (req, res, ctx) => { return res( ctx.data({ createLead: { id: 'mock-uuid', resultCode: 1015, note: 'Lead processing complete' } }) ); }),
graphql.query('GetLeadStatus', (req, res, ctx) => { return res( ctx.data({ getLeadStatus: { id: req.variables.id, resultCode: 1015, updatedAt: new Date().toISOString(), bidValue: '$15.00' } }) ); })];Integration Test Checklist
Before Testing
- Sandbox credentials configured
- Lead source ID verified
- Test data prepared
- Logging enabled
Core Functionality
- Authentication succeeds
- Token caching works
- Lead submission works
- Status lookup works (optional)
- CRM submission works
Error Handling
- Missing required fields rejected
- Invalid formats rejected
- Authentication errors handled
- Rate limits handled
- Timeouts handled
Edge Cases
- Duplicate leads detected
- Token refresh on expiry
- Concurrent submissions
- Large field values
Performance
- Response times acceptable
- Request throughput doesn’t exceed limits
- Connection pooling works
Debugging Tips
Enable Verbose Logging
const mlaClient = new MLAClient({ debug: true, logLevel: 'verbose'});Inspect GraphQL Responses
async function debugRequest(query, variables) { console.log('Request:', JSON.stringify({ query, variables }, null, 2));
const response = await fetch(API_URL, { method: 'POST', headers: headers, body: JSON.stringify({ query, variables }) });
const text = await response.text(); console.log('Response:', text);
return JSON.parse(text);}Check Lead Status in Detail
// Query full lead status for debuggingconst debugQuery = ` query GetLeadStatus($id: ID!) { getLeadStatus(id: $id) { id resultCode updatedAt partnerLeadId bidValue } }`;Related
- Environments - Environment details
- Result Codes - Understand outcomes