Back to Repositories

Testing IpdataCo IP Lookup Integration in geocoder

This test suite validates the IpdataCo lookup functionality in the Geocoder gem, focusing on IP address geolocation capabilities and API integration. The tests cover various IP address types, error handling, and API authentication scenarios.

Test Coverage Overview

The test suite provides comprehensive coverage of the IpdataCo IP lookup functionality, including:

  • Standard IP address lookups and result validation
  • Special IP cases (loopback, private addresses)
  • Response parsing and error handling
  • API authentication and key validation

Implementation Analysis

The testing approach utilizes Ruby’s Test::Unit framework with custom assertions and mocking capabilities. The implementation follows a structured pattern of setup, execution, and verification, leveraging Geocoder’s configuration flexibility and WebMock for HTTP request testing.

Technical Details

Key technical components include:

  • Test::Unit as the testing framework
  • WebMock for HTTP request stubbing
  • Custom GeocoderTestCase class for shared functionality
  • Mock HTTP responses for error scenarios

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolation of external services using WebMock
  • Comprehensive error case coverage
  • Clear test method naming conventions
  • Proper setup and teardown management
  • Explicit assertion messages

alexreisner/geocoder

test/unit/lookups/ipdata_co_test.rb

            
# encoding: utf-8
require 'test_helper'

class IpdataCoTest < GeocoderTestCase

  def setup
    super
    Geocoder.configure(ip_lookup: :ipdata_co)
  end

  def test_result_on_ip_address_search
    result = Geocoder.search("74.200.247.59").first
    assert result.is_a?(Geocoder::Result::IpdataCo)
  end

  def test_result_on_loopback_ip_address_search
    result = Geocoder.search("127.0.0.1").first
    assert_equal "127.0.0.1", result.ip
    assert_equal 'RD',        result.country_code
    assert_equal "Reserved",  result.country
  end

  def test_result_on_private_ip_address_search
    result = Geocoder.search("172.19.0.1").first
    assert_equal "172.19.0.1", result.ip
    assert_equal 'RD',         result.country_code
    assert_equal "Reserved",   result.country
  end

  def test_invalid_json
    Geocoder.configure(:always_raise => [Geocoder::ResponseParseError])
    assert_raise Geocoder::ResponseParseError do
      Geocoder.search("8.8.8", ip_address: true)
    end
  end

  def test_result_components
    result = Geocoder.search("74.200.247.59").first
    assert_equal "Jersey City, NJ 07302, United States", result.address
  end

  def test_not_authorized
    Geocoder.configure(always_raise: [Geocoder::RequestDenied])
    lookup = Geocoder::Lookup.get(:ipdata_co)
      assert_raises Geocoder::RequestDenied do
        response = MockHttpResponse.new(code: 403)
        lookup.send(:check_response_for_errors!, response)
    end
  end

  def test_api_key
    Geocoder.configure(:api_key => 'XXXX')

    # HACK: run the code once to add the api key to the HTTP request headers
    Geocoder.search('8.8.8.8')
    # It's really hard to 'un-monkey-patch' the base lookup class here

    require 'webmock/test_unit'
    WebMock.enable!
    stubbed_request = WebMock.stub_request(:get, "https://api.ipdata.co/8.8.8.8?api-key=XXXX").to_return(status: 200)

    g = Geocoder::Lookup::IpdataCo.new
    g.send(:actual_make_api_request, Geocoder::Query.new('8.8.8.8'))
    assert_requested(stubbed_request)

    WebMock.reset!
    WebMock.disable!
  end
end