Skip to main content
This guide provides code examples and automation strategies for comprehensive GEFT testing.

Session Management

Basic Testing Workflow

// Example testing workflow
async function testGeftScenario(scenarioName) {
  try {
    // 1. Authenticate
    const authResponse = await authenticate();

    // 2. Create session with test data
    const sessionData = getTestScenarioData(scenarioName);
    const session = await createSession(sessionData, authResponse.access_token);

    // 3. Monitor events
    setupEventMonitoring(session.sessionId);

    // 4. Launch iframe
    launchGeftIframe(session.sessionId);

    // 5. Poll status
    const finalStatus = await pollSessionStatus(
      session.sessionId,
      authResponse.access_token
    );

    return {
      scenario: scenarioName,
      success: finalStatus.status === 'Completed',
      status: finalStatus
    };
  } catch (error) {
    console.error(`Test failed for ${scenarioName}:`, error);
    throw error;
  }
}

Test Data Management

function getTestScenarioData(scenario) {
  const scenarios = {
    'Happy1': {
      referenceId: 'Happy1',
      payor: {
        firstName: 'John',
        lastName: 'Doe',
        email: 'j.doe@gmail.com'
      }
    },
    'Happy2': {
      referenceId: 'Happy2',
      payor: {
        firstName: 'Steve',
        lastName: 'Diamond',
        email: 'steve.diamond@example.com'
      }
    },
    'Unhappy1': {
      referenceId: 'Unhappy1',
      payor: {
        firstName: 'Joe',
        lastName: 'Fails',
        email: 'joe.fails@example.com'
      }
    }
  };

  return {
    ...scenarios[scenario],
    type: 'EFT',
    direction: 'DEBIT',
    currency: 'CAD',
    options: {
      guarantee: { enable: true },
      notificationPreferences: { language: 'EN' }
    }
  };
}

Event Testing

Event Monitoring Setup

function setupEventMonitoring(sessionId) {
  const events = [];

  window.addEventListener('message', function(e) {
    if (e.data && e.data.sessionId === sessionId) {
      events.push({
        timestamp: new Date(),
        event: e.data
      });

      console.log('Test Event:', e.data);

      // Verify expected events for scenario
      validateEventSequence(events);
    }
  });

  return events;
}

Event Validation

function validateEventSequence(events) {
  const eventSteps = events.map(e => e.event.Step);

  // Validate event order for successful flow
  const expectedSuccess = [
    'APP_MOUNTED',
    'INSTITUTION_SELECTED',
    'SUBMIT_CREDENTIAL',
    'ACCOUNT_SELECTED',
    'COMPONENT_DEPOSIT_CONTINUE',
    'GUARANTEE_OFFERED',
    'COMPONENT_PAD_DOWNLOADED',
    'SUCCESS'
  ];

  // Check if events follow expected pattern
  let expectedIndex = 0;
  for (const step of eventSteps) {
    if (step === expectedSuccess[expectedIndex]) {
      expectedIndex++;
    }
  }

  return expectedIndex === expectedSuccess.length;
}

Automated Testing

Full Test Suite

// Run all test scenarios
async function runFullTestSuite() {
  const scenarios = [
    'Happy1',
    'Happy2',
    'Happy3',
    'Unhappy1',
    'Unhappy2',
    'Unhappy3'
  ];

  const results = [];

  for (const scenario of scenarios) {
    try {
      const result = await testGeftScenario(scenario);
      results.push(result);
      console.log(`✓ ${scenario} passed`);
    } catch (error) {
      results.push({
        scenario,
        success: false,
        error: error.message
      });
      console.log(`✗ ${scenario} failed:`, error.message);
    }
  }

  return results;
}

Parallel Testing

// Run multiple scenarios in parallel
async function runParallelTests(scenarios) {
  const promises = scenarios.map(scenario => testGeftScenario(scenario));

  try {
    const results = await Promise.allSettled(promises);
    return results.map((result, index) => ({
      scenario: scenarios[index],
      success: result.status === 'fulfilled',
      data: result.value || result.reason
    }));
  } catch (error) {
    console.error('Parallel test execution failed:', error);
    throw error;
  }
}

Authentication Testing

API Key Configuration

// Configure API authentication headers
const API_CONFIG = {
  baseUrl: 'https://payments-uat.flinksapp.com',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.GEFT_API_KEY,
    'x-client-id': process.env.GEFT_CLIENT_ID
  }
};

async function createSession(sessionData) {
  const response = await fetch(`${API_CONFIG.baseUrl}/api/v2/sessions`, {
    method: 'POST',
    headers: API_CONFIG.headers,
    body: JSON.stringify(sessionData)
  });

  if (!response.ok) {
    throw new Error(`Session creation failed: ${response.status}`);
  }

  return response.json();
}

Status Polling

Robust Polling Implementation

async function pollSessionStatus(sessionId, maxAttempts = 20) {
  const pollInterval = 30000; // 30 seconds

  for (let i = 0; i < maxAttempts; i++) {
    try {
      const response = await fetch(
        `https://payments-uat.flinksapp.com/api/v2/sessions/${sessionId}/status`
      );

      if (!response.ok) {
        throw new Error(`Status check failed: ${response.status}`);
      }

      const status = await response.json();

      // Check for terminal states
      if (['Completed', 'Failed', 'Canceled', 'Expired'].includes(status.status)) {
        return status;
      }

      // Wait before next poll
      await new Promise(resolve => setTimeout(resolve, pollInterval));
    } catch (error) {
      console.error('Status polling error:', error);
      if (i === maxAttempts - 1) throw error;
    }
  }

  throw new Error('Polling timeout - session status unknown');
}

Error Handling

Comprehensive Error Testing

async function testErrorHandling() {
  const errorTests = [
    {
      name: 'Invalid credentials',
      test: () => authenticateWithWrongCredentials(),
      expectedError: 'Unauthorized'
    },
    {
      name: 'Malformed session data',
      test: () => createSessionWithInvalidData(),
      expectedError: 'Bad Request'
    },
    {
      name: 'Network timeout',
      test: () => testWithNetworkDelay(),
      expectedError: 'Timeout'
    }
  ];

  const results = [];

  for (const errorTest of errorTests) {
    try {
      await errorTest.test();
      results.push({
        test: errorTest.name,
        success: false,
        error: 'Expected error was not thrown'
      });
    } catch (error) {
      const success = error.message.includes(errorTest.expectedError);
      results.push({
        test: errorTest.name,
        success,
        error: success ? null : `Unexpected error: ${error.message}`
      });
    }
  }

  return results;
}

Performance Testing

Load Testing

async function performanceTest() {
  const concurrentSessions = 5;
  const sessionPromises = [];

  console.log(`Starting ${concurrentSessions} concurrent sessions...`);

  for (let i = 0; i < concurrentSessions; i++) {
    sessionPromises.push(
      measureSessionTime(`Happy1_${i}`)
    );
  }

  const results = await Promise.allSettled(sessionPromises);

  const successful = results.filter(r => r.status === 'fulfilled');
  const failed = results.filter(r => r.status === 'rejected');

  console.log(`Performance results:`);
  console.log(`Successful: ${successful.length}`);
  console.log(`Failed: ${failed.length}`);

  if (successful.length > 0) {
    const times = successful.map(r => r.value.duration);
    const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
    console.log(`Average completion time: ${avgTime}ms`);
  }
}

async function measureSessionTime(referenceId) {
  const startTime = Date.now();

  try {
    const result = await testGeftScenario('Happy1', { referenceId });
    return {
      success: true,
      duration: Date.now() - startTime,
      result
    };
  } catch (error) {
    return {
      success: false,
      duration: Date.now() - startTime,
      error: error.message
    };
  }
}

CI/CD Integration

Test Runner for CI

// test-runner.js - For use in CI/CD pipelines
const { testGeftScenario, runFullTestSuite } = require('./geft-tests');

async function ciTestRunner() {
  console.log('Starting GEFT integration tests...');

  try {
    const results = await runFullTestSuite();

    const passed = results.filter(r => r.success).length;
    const failed = results.filter(r => !r.success).length;

    console.log(`Tests completed: ${passed} passed, ${failed} failed`);

    if (failed > 0) {
      console.error('Failed tests:', results.filter(r => !r.success));
      process.exit(1);
    }

    console.log('All tests passed!');
    process.exit(0);
  } catch (error) {
    console.error('Test suite failed:', error);
    process.exit(1);
  }
}

if (require.main === module) {
  ciTestRunner();
}

module.exports = { ciTestRunner };

Next Steps