Skip to content

API Testing Guide ​

This guide documents the testing approach and lessons learned while validating the cyber.trackr.live OpenAPI specification.

Testing Strategy ​

We use three levels of testing to ensure our OpenAPI specification is accurate:

  1. Syntax Validation - Ensure the spec is valid OpenAPI 3.1.1
  2. Completeness Checks - Verify all endpoints and schemas are documented
  3. Live Validation - Test against the real API to ensure accuracy

Key Lessons Learned ​

1. Faraday URL Construction ​

When using Faraday with a base URL that includes a path (like /api), be careful with leading slashes:

ruby
# WRONG - This goes to https://cyber.trackr.live/ (ignores /api)
client = Faraday.new(url: 'https://cyber.trackr.live/api')
response = client.get('/')  # Leading slash overwrites base path!

# CORRECT - Use full path
client = Faraday.new(url: 'https://cyber.trackr.live')
response = client.get('/api')

2. Redirect Handling ​

The API redirects from /api/ to /api (trailing slash removed). Faraday needs proper middleware setup:

ruby
Faraday.new do |f|
  f.headers['Accept'] = 'application/json'
  f.response :json, content_type: /\bjson$/  # Parse JSON first
  f.response :follow_redirects              # Then handle redirects
end

Important: The order matters! Put JSON parsing before redirect following.

3. JSON Parsing After Redirects ​

When Faraday follows redirects, the JSON middleware might not automatically parse the response. Solution:

ruby
def parse_response(response)
  response.body.is_a?(String) ? JSON.parse(response.body) : response.body
end

4. Error Response Patterns ​

The API has specific error behaviors:

  • 404: Invalid endpoints (e.g., /api/invalid)
  • 500: Invalid parameter formats (e.g., V-INVALID, CCI-INVALID)

This is documented in our tests:

ruby
def test_parameter_validation
  # Invalid V-ID returns 500, not 404
  response = @client.get('/api/stig/.../V-INVALID')
  assert_equal 500, response.status
  
  # Invalid endpoint returns 404
  response = @client.get('/api/invalid')
  assert_equal 404, response.status
end

Running Tests ​

Quick Validation ​

bash
# Just validate the OpenAPI spec syntax
ruby test/openapi_validation_test.rb

Full Test Suite ​

bash
# Run all tests including live API validation
ruby test/openapi_validation_test.rb && \
ruby test/spec_completeness_test.rb && \
ruby test/live_api_validation_test.rb

Debugging API Issues ​

If tests fail, enable request logging:

ruby
# In test/live_api_validation_test.rb, uncomment:
f.response :logger # Log requests for debugging

Testing with curl ​

Always test endpoints with curl first to understand the actual behavior:

bash
# Test JSON response
curl -s -H "Accept: application/json" "https://cyber.trackr.live/api" | jq .

# Check headers
curl -I -H "Accept: application/json" "https://cyber.trackr.live/api/"

# Test specific endpoint
curl -s "https://cyber.trackr.live/api/stig/Juniper_SRX_Services_Gateway_ALG/3/3" | jq .

Test File Descriptions ​

openapi_validation_test.rb ​

  • Uses openapi3_parser gem for validation
  • Checks OpenAPI 3.1.1 compliance
  • Validates nullable syntax (anyOf with type: "null")
  • Ensures all schema references resolve

spec_completeness_test.rb ​

  • Verifies all required endpoints exist
  • Checks schema completeness
  • Validates parameter patterns are consistent
  • Ensures examples match their patterns

live_api_validation_test.rb ​

  • Tests against real cyber.trackr.live API
  • Validates response structures
  • Samples actual data
  • Verifies error handling

Common Issues and Solutions ​

Issue: Getting HTML instead of JSON ​

Symptom: JSON::ParserError: unexpected character: '<!DOCTYPE'

Causes:

  1. Missing Accept: application/json header
  2. Incorrect URL path construction
  3. Not following redirects

Solution: Check all three items above.

Issue: Parameter validation returns unexpected status ​

Symptom: Expected 404 but got 500

Solution: The API returns 500 for invalid parameter formats. Update tests and documentation to reflect actual behavior.

Issue: Tests pass individually but fail together ​

Symptom: Warnings appear in wrong tests

Solution: Tests run in random order. Use clear test names in output:

ruby
puts "\n[#{__method__}] Test output here"

Best Practices ​

  1. Always test with curl first - Understand actual API behavior
  2. Check both with and without trailing slashes - APIs may redirect
  3. Test error cases - Invalid parameters reveal API patterns
  4. Use proper assertions - Don't just print, assert expected behavior
  5. Document actual behavior - Even if it's not ideal (like 500 for invalid params)

Continuous Validation ​

To ensure the spec stays accurate:

  1. Run tests before any spec changes
  2. Update tests when discovering new API behaviors
  3. Document any quirks or unexpected behaviors
  4. Keep example data up-to-date

Released under the Apache-2.0 License.