Back to Repositories

Testing IP Address Detection and Validation Workflows in Geocoder

This test suite validates the functionality of the Query class in the Geocoder gem, focusing on IP address detection, coordinate handling, and address validation.

Test Coverage Overview

The test suite provides comprehensive coverage of the Geocoder::Query class functionality:

  • IPv4 and IPv6 address detection and validation
  • Coordinate parsing and sanitization
  • Internal, loopback, and private IP address identification
  • Blank query handling
  • Custom lookup configuration

Implementation Analysis

The testing approach utilizes Ruby’s standard unit testing framework with a focus on discrete functionality verification.

Key patterns include:
  • Systematic true/false assertions for IP address detection
  • Input sanitization verification
  • Configuration override testing
  • Edge case handling for blank and malformed inputs

Technical Details

Testing infrastructure includes:

  • Ruby’s built-in test framework
  • GeocoderTestCase as the base test class
  • IPAddr library for IP address handling
  • Custom configuration options for lookup services

Best Practices Demonstrated

The test suite exemplifies strong testing practices:

  • Isolated test cases for specific functionality
  • Comprehensive edge case coverage
  • Clear test method naming conventions
  • Proper setup of test configurations
  • Effective use of assertions for validation

alexreisner/geocoder

test/unit/query_test.rb

            
# encoding: utf-8
require 'test_helper'

class QueryTest < GeocoderTestCase

  def test_detect_ipv4
    assert Geocoder::Query.new("232.65.123.94").ip_address?
    ip = IPAddr.new("232.65.123.94")
    assert Geocoder::Query.new(ip).ip_address?
  end

  def test_detect_ipv6
    assert Geocoder::Query.new("3ffe:0b00:0000:0000:0001:0000:0000:000a").ip_address?
    ip = IPAddr.new("3ffe:0b00:0000:0000:0001:0000:0000:000a")
    assert Geocoder::Query.new(ip).ip_address?
  end

  def test_detect_non_ip_address
    assert !Geocoder::Query.new("232.65.123.94.43").ip_address?
    assert !Geocoder::Query.new("::ffff:123.456.789").ip_address?
  end

  def test_strip_trailing_whitespace_for_ip_address_query
    text = "77.251.213.1\n"
    query = Geocoder::Query.new(text)
    assert_equal text[0...-1], query.sanitized_text
  end

  def test_blank_query_detection
    assert Geocoder::Query.new(nil).blank?
    assert Geocoder::Query.new("").blank?
    assert Geocoder::Query.new("\t  ").blank?
    assert !Geocoder::Query.new("a").blank?
    assert !Geocoder::Query.new("Москва").blank? # no ASCII characters
    assert !Geocoder::Query.new("\na").blank?

    assert Geocoder::Query.new(nil, :params => {}).blank?
    assert !Geocoder::Query.new(nil, :params => {:woeid => 1234567}).blank?
  end

  def test_blank_query_detection_for_coordinates
    assert Geocoder::Query.new([nil,nil]).blank?
    assert Geocoder::Query.new([87,nil]).blank?
  end

  def test_coordinates_detection
    assert Geocoder::Query.new("51.178844,5").coordinates?
    assert Geocoder::Query.new("51.178844, -1.826189").coordinates?
    assert !Geocoder::Query.new("232.65.123").coordinates?
    assert !Geocoder::Query.new("Test\n51.178844, -1.826189").coordinates?
  end

  def test_internal_ip_address
    assert Geocoder::Query.new("127.0.0.1").internal_ip_address?
    assert Geocoder::Query.new("172.19.0.1").internal_ip_address?
    assert Geocoder::Query.new("10.100.100.1").internal_ip_address?
    assert Geocoder::Query.new("192.168.0.1").internal_ip_address?
    assert !Geocoder::Query.new("232.65.123.234").internal_ip_address?
  end

  def test_loopback_ip_address
    assert Geocoder::Query.new("127.0.0.1").loopback_ip_address?
    assert !Geocoder::Query.new("232.65.123.234").loopback_ip_address?
  end

  def test_private_ip_address
    assert Geocoder::Query.new("172.19.0.1").private_ip_address?
    assert Geocoder::Query.new("10.100.100.1").private_ip_address?
    assert Geocoder::Query.new("192.168.0.1").private_ip_address?
    assert !Geocoder::Query.new("127.0.0.1").private_ip_address?
    assert !Geocoder::Query.new("232.65.123.234").private_ip_address?
  end

  def test_sanitized_text_with_array
    q = Geocoder::Query.new([43.1313,11.3131])
    assert_equal "43.1313,11.3131", q.sanitized_text
  end

  def test_custom_lookup
    query = Geocoder::Query.new("address", :lookup => :nominatim)
    assert_instance_of Geocoder::Lookup::Nominatim, query.lookup
  end

  def test_force_specify_ip_address
    Geocoder.configure({:ip_lookup => :google})
    query = Geocoder::Query.new("address", {:ip_address => true})
    assert !query.ip_address?
    assert_instance_of Geocoder::Lookup::Google, query.lookup
  end

  def test_force_specify_street_address
    Geocoder.configure({:lookup => :google, :ip_lookup => :freegeoip})
    query = Geocoder::Query.new("4.1.0.2", {street_address: true})
    assert query.ip_address?
    assert_instance_of Geocoder::Lookup::Google, query.lookup
  end

  def test_force_specify_ip_address_with_ip_lookup
    query = Geocoder::Query.new("address", {:ip_address => true, :ip_lookup => :google})
    assert !query.ip_address?
    assert_instance_of Geocoder::Lookup::Google, query.lookup
  end
end