Refactored the MaxMind database class to not use static methods in order to make testing the integration class easier

This commit is contained in:
Christopher Allford 2020-01-10 02:09:51 -08:00
parent 26e0b71fce
commit 19ded6609d
5 changed files with 76 additions and 26 deletions

View File

@ -178,7 +178,8 @@ class WC_Geolocation {
*/
public static function get_local_database_path( $deprecated = '2' ) {
wc_deprecated_function( 'WC_Geolocation::get_local_database_path', '3.9.0' );
return WC_Integration_MaxMind_Geolocation_Database::get_database_path();
$integration = wc()->integrations->get_integration( 'woocommerce_maxmind_geolocation' );
return $integration->get_database_path();
}
/**
@ -189,7 +190,8 @@ class WC_Geolocation {
*/
public static function update_database() {
wc_deprecated_function( 'WC_Geolocation::update_database', '3.9.0' );
WC_Integration_MaxMind_Geolocation::update_database();
$integration = wc()->integrations->get_integration( 'woocommerce_maxmind_geolocation' );
$integration->update_database();
}
/**

View File

@ -52,4 +52,19 @@ class WC_Integrations {
public function get_integrations() {
return $this->integrations;
}
/**
* Return a desired integration.
*
* @param string $id The id of the integration to get.
*
* @return mixed|null The integration if one is found, otherwise null.
*/
public function get_integration( $id ) {
if ( isset( $this->integrations[ $id ] ) ) {
return $this->integrations[ $id ];
}
return null;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
* WC Integration MaxMind Geolocation Database
* The database service class file.
*
* @version 3.9.0
* @package WooCommerce/Integrations
@ -9,11 +9,11 @@
defined( 'ABSPATH' ) || exit;
/**
* WC Integration MaxMind Geolocation Database
* The service class responsible for interacting with MaxMind databases.
*
* @since 3.9.0
*/
class WC_Integration_MaxMind_Geolocation_Database {
class WC_Integration_MaxMind_Database_Service {
/**
* The name of the MaxMind database to utilize.
@ -30,7 +30,7 @@ class WC_Integration_MaxMind_Geolocation_Database {
*
* @return string The local database path.
*/
public static function get_database_path() {
public function get_database_path() {
$database_path = WP_CONTENT_DIR . '/uploads/' . self::DATABASE . self::DATABASE_EXTENSION;
/**
@ -62,7 +62,7 @@ class WC_Integration_MaxMind_Geolocation_Database {
* @param string $license_key The license key to be used when downloading the database.
* @return string|WP_Error The path to the database file or an error if invalid.
*/
public static function download_database( $license_key ) {
public function download_database( $license_key ) {
$download_uri = add_query_arg(
array(
'edition_id' => self::DATABASE,
@ -119,11 +119,11 @@ class WC_Integration_MaxMind_Geolocation_Database {
* @param string $ip_address The IP address to find the country code for.
* @return string|null The country code for the IP address, or null if none was found.
*/
public static function get_iso_country_code_for_ip( $ip_address ) {
public function get_iso_country_code_for_ip( $ip_address ) {
$country_code = null;
try {
$reader = new MaxMind\Db\Reader( self::get_database_path() );
$reader = new MaxMind\Db\Reader( $this->get_database_path() );
$data = $reader->get( $ip_address );
if ( isset( $data['country']['iso_code'] ) ) {

View File

@ -8,7 +8,7 @@
defined( 'ABSPATH' ) || exit;
require_once 'class-wc-integration-maxmind-geolocation-database.php';
require_once 'class-wc-integration-maxmind-database-service.php';
/**
* WC Integration MaxMind Geolocation
@ -17,6 +17,13 @@ require_once 'class-wc-integration-maxmind-geolocation-database.php';
*/
class WC_Integration_MaxMind_Geolocation extends WC_Integration {
/**
* The service responsible for interacting with the MaxMind database.
*
* @var WC_Integration_MaxMind_Database_Service
*/
private $database_service;
/**
* Initialize the integration.
*/
@ -25,6 +32,19 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
$this->method_title = __( 'WooCommerce MaxMind Geolocation', 'woocommerce' );
$this->method_description = __( 'An integration for utilizing MaxMind to do Geolocation lookups.', 'woocommerce' );
// We will need a service for interacting with the MaxMind database.
/**
* Supports overriding the database service to be used.
*
* @since 3.9.0
* @return mixed|null The geolocation database service.
*/
$this->database_service = apply_filters( 'woocommerce_maxmind_geolocation_database_service', null );
if ( null === $this->database_service ) {
$this->database_service = new WC_Integration_MaxMind_Database_Service();
}
$this->init_form_fields();
$this->init_settings();
@ -47,7 +67,7 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
// Bind to the scheduled updater action.
if ( $bind_updater ) {
add_action( 'woocommerce_geoip_updater', array( __CLASS__, 'update_database' ) );
add_action( 'woocommerce_geoip_updater', array( $this, 'update_database' ) );
}
// Bind to the geolocation filter for MaxMind database lookups.
@ -91,7 +111,7 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
}
// Check the license key by attempting to download the Geolocation database.
$tmp_database_path = WC_Integration_MaxMind_Geolocation_Database::download_database( $value );
$tmp_database_path = $this->database_service->download_database( $value );
if ( is_wp_error( $tmp_database_path ) ) {
WC_Admin_Settings::add_error( $tmp_database_path->get_error_message() );
@ -112,14 +132,14 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
*
* @param string|null $new_database_path The path to the new database file. Null will fetch a new archive.
*/
public static function update_database( $new_database_path = null ) {
public function update_database( $new_database_path = null ) {
// Allow us to easily interact with the filesystem.
require_once ABSPATH . 'wp-admin/includes/file.php';
WP_Filesystem();
global $wp_filesystem;
// Remove any existing archives to comply with the MaxMind TOS.
$target_database_path = WC_Integration_MaxMind_Geolocation_Database::get_database_path();
$target_database_path = $this->database_service->get_database_path();
if ( $wp_filesystem->exists( $target_database_path ) ) {
$wp_filesystem->delete( $target_database_path );
}
@ -128,12 +148,12 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
$tmp_database_path = $new_database_path;
} else {
// We can't download a database if there's no license key configured.
$license_key = ( new WC_Integration_MaxMind_Geolocation() )->get_option( 'license_key' );
$license_key = $this->get_option( 'license_key' );
if ( empty( $license_key ) ) {
return;
}
$tmp_database_path = WC_Integration_MaxMind_Geolocation_Database::download_database( $license_key );
$tmp_database_path = $this->database_service->download_database( $license_key );
if ( is_wp_error( $tmp_database_path ) ) {
wc_get_logger()->notice( $tmp_database_path->get_error_message(), array( 'source' => 'maxmind-geolocation' ) );
return;
@ -161,7 +181,7 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
return $country_code;
}
$country_code = WC_Integration_MaxMind_Geolocation_Database::get_iso_country_code_for_ip( $ip_address );
$country_code = $this->database_service->get_iso_country_code_for_ip( $ip_address );
return $country_code ? $country_code : false;
}

View File

@ -9,7 +9,6 @@
* Class WC_Tests_MaxMind_Database
*/
class WC_Tests_MaxMind_Database extends WC_Unit_Test_Case {
/**
* Run setup code for unit tests.
*/
@ -26,17 +25,22 @@ class WC_Tests_MaxMind_Database extends WC_Unit_Test_Case {
* @expectedDeprecated woocommerce_geolocation_local_database_path
*/
public function test_database_path_filters() {
$path = WC_Integration_MaxMind_Geolocation_Database::get_database_path();
$this->assertEquals( WP_CONTENT_DIR . '/uploads/' . WC_Integration_MaxMind_Geolocation_Database::DATABASE . WC_Integration_MaxMind_Geolocation_Database::DATABASE_EXTENSION, $path );
$database_service = $this->getMockBuilder( 'WC_Integration_MaxMind_Database_Service' )
->setMethods( null )
->disableOriginalConstructor()
->getMock();
$path = $database_service->get_database_path();
$this->assertEquals( WP_CONTENT_DIR . '/uploads/' . WC_Integration_MaxMind_Database_Service::DATABASE . WC_Integration_MaxMind_Database_Service::DATABASE_EXTENSION, $path );
add_filter( 'woocommerce_geolocation_local_database_path', array( $this, 'filter_database_path_deprecated' ), 1, 2 );
$path = WC_Integration_MaxMind_Geolocation_Database::get_database_path();
$path = $database_service->get_database_path();
remove_filter( 'woocommerce_geolocation_local_database_path', array( $this, 'filter_database_path' ) );
$this->assertEquals( '/deprecated_filter', $path );
add_filter( 'woocommerce_geolocation_local_database_path', array( $this, 'filter_database_path' ) );
$path = WC_Integration_MaxMind_Geolocation_Database::get_database_path();
$path = $database_service->get_database_path();
remove_filter( 'woocommerce_geolocation_local_database_path', array( $this, 'filter_database_path' ) );
$this->assertEquals( '/filter', $path );
@ -46,9 +50,13 @@ class WC_Tests_MaxMind_Database extends WC_Unit_Test_Case {
* Tests that the database download works as expected.
*/
public function test_download_database_works() {
$database_service = $this->getMockBuilder( 'WC_Integration_MaxMind_Database_Service' )
->setMethods( null )
->disableOriginalConstructor()
->getMock();
$expected_database = '/tmp/GeoLite2-Country_20200100/GeoLite2-Country.mmdb';
$result = WC_Integration_MaxMind_Geolocation_Database::download_database( 'testing_license' );
$result = $database_service->download_database( 'testing_license' );
$this->assertEquals( $expected_database, $result );
@ -61,17 +69,22 @@ class WC_Tests_MaxMind_Database extends WC_Unit_Test_Case {
* Tests the that database download wraps the download and extraction errors.
*/
public function test_download_database_wraps_errors() {
$result = WC_Integration_MaxMind_Geolocation_Database::download_database( 'invalid_license' );
$database_service = $this->getMockBuilder( 'WC_Integration_MaxMind_Database_Service' )
->setMethods( null )
->disableOriginalConstructor()
->getMock();
$result = $database_service->download_database( 'invalid_license' );
$this->assertWPError( $result );
$this->assertEquals( 'woocommerce_maxmind_geolocation_database_license_key', $result->get_error_code() );
$result = WC_Integration_MaxMind_Geolocation_Database::download_database( 'generic_error' );
$result = $database_service->download_database( 'generic_error' );
$this->assertWPError( $result );
$this->assertEquals( 'woocommerce_maxmind_geolocation_database_download', $result->get_error_code() );
$result = WC_Integration_MaxMind_Geolocation_Database::download_database( 'archive_error' );
$result = $database_service->download_database( 'archive_error' );
$this->assertWPError( $result );
$this->assertEquals( 'woocommerce_maxmind_geolocation_database_archive', $result->get_error_code() );