diff --git a/client/components/data/query-geo/README.md b/client/components/data/query-geo/README.md
deleted file mode 100644
index cb2418932506e..0000000000000
--- a/client/components/data/query-geo/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-Query Sites
-===========
-
-`` is a React component used in managing network requests for browser IP geolocation.
-
-## Usage
-
-Render the component. The component does not accept any children, nor does it render any of its own.
-
-```jsx
-function MyComponent() {
- return
-}
-```
-
-## Props
-
-This component does not accept any props.
diff --git a/client/components/data/query-geo/index.jsx b/client/components/data/query-geo/index.jsx
deleted file mode 100644
index 5f243262c129d..0000000000000
--- a/client/components/data/query-geo/index.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-/** @format */
-
-/**
- * External dependencies
- */
-
-import PropTypes from 'prop-types';
-import { Component } from 'react';
-import { connect } from 'react-redux';
-
-/**
- * Internal dependencies
- */
-import { isRequestingGeo } from 'state/geo/selectors';
-import { requestGeo } from 'state/geo/actions';
-
-class QueryGeo extends Component {
- componentWillMount() {
- if ( ! this.props.requesting ) {
- this.props.requestGeo();
- }
- }
-
- render() {
- return null;
- }
-}
-
-QueryGeo.propTypes = {
- requesting: PropTypes.bool,
- requestGeo: PropTypes.func,
-};
-
-export default connect( state => ( { requesting: isRequestingGeo( state ) } ), { requestGeo } )(
- QueryGeo
-);
diff --git a/client/components/language-picker/index.jsx b/client/components/language-picker/index.jsx
index 4cd0b1e275463..cf7f30957f002 100644
--- a/client/components/language-picker/index.jsx
+++ b/client/components/language-picker/index.jsx
@@ -14,10 +14,9 @@ import { find, isString, noop } from 'lodash';
/**
* Internal dependencies
*/
-import { getGeoCountryShort } from 'state/geo/selectors';
-import QueryGeo from 'components/data/query-geo';
import LanguagePickerModal from './modal';
import QueryLanguageNames from 'components/data/query-language-names';
+import { requestGeoLocation } from 'state/data-layer/http-data/getters';
import { getLanguageCodeLabels } from './utils';
export class LanguagePicker extends PureComponent {
@@ -174,13 +173,12 @@ export class LanguagePicker extends PureComponent {
{ this.renderModal( language.langSlug ) }
-
);
}
}
-export default connect( state => ( {
- countryCode: getGeoCountryShort( state ),
-} ) )( localize( LanguagePicker ) );
+export default connect( () => ( { countryCode: requestGeoLocation().data } ) )(
+ localize( LanguagePicker )
+);
diff --git a/client/lib/abtest/README.md b/client/lib/abtest/README.md
index b00c8ee6b6932..d120d69d7180d 100644
--- a/client/lib/abtest/README.md
+++ b/client/lib/abtest/README.md
@@ -68,7 +68,7 @@ Also, the user's variation is saved in local storage. You can see this in Chrome
Here's another example with country targeting:
```jsx
-const userCountryCode = getGeoCountryShort( state );
+const userCountryCode = requestGeoLocation().data;
let buttonWording;
if ( abtest( 'freeTrialButtonWordingForIndia', userCountryCode ) === 'startFreeTrial' ) {
@@ -161,7 +161,7 @@ You would need to update [config/default.json](https://github.com/Automattic/wp-
"knownABTestKeys": [
"freeTrialButtonWording"
]
-
+
"overrideABTests": [
[ "freeTrialButtonWording_201502160", "startFreeTrial" ]
]
diff --git a/client/my-sites/checkout/checkout/checkout.jsx b/client/my-sites/checkout/checkout/checkout.jsx
index 2b2c01a4c2b09..665853d0d0f05 100644
--- a/client/my-sites/checkout/checkout/checkout.jsx
+++ b/client/my-sites/checkout/checkout/checkout.jsx
@@ -32,7 +32,6 @@ import { managePurchase } from 'me/purchases/paths';
import SubscriptionLengthPicker from 'blocks/subscription-length-picker';
import QueryContactDetailsCache from 'components/data/query-contact-details-cache';
import QueryStoredCards from 'components/data/query-stored-cards';
-import QueryGeo from 'components/data/query-geo';
import QuerySitePlans from 'components/data/query-site-plans';
import QueryPlans from 'components/data/query-plans';
import SecurePaymentForm from './secure-payment-form';
@@ -610,7 +609,6 @@ export class Checkout extends React.Component {
-
{ this.content() }
diff --git a/client/state/data-layer/http-data/getters.js b/client/state/data-layer/http-data/getters.js
new file mode 100644
index 0000000000000..6b299505d237a
--- /dev/null
+++ b/client/state/data-layer/http-data/getters.js
@@ -0,0 +1,38 @@
+/** @format */
+/**
+ * Internal dependencies
+ */
+import makeJsonSchemaParser from 'lib/make-json-schema-parser';
+import { http as rawHttp } from 'state/http/actions';
+import { requestHttpData } from 'state/data-layer/http-data/common';
+
+export const requestGeoLocation = () =>
+ requestHttpData(
+ 'geo',
+ rawHttp( {
+ method: 'GET',
+ url: 'https://public-api.wordpress.com/geo/',
+ } ),
+ {
+ fromApi: makeJsonSchemaParser(
+ {
+ type: 'object',
+ properties: {
+ body: {
+ type: [ 'object', 'null' ],
+ properties: {
+ latitude: { type: 'string' },
+ longitude: { type: 'string' },
+ country_short: { type: 'string' },
+ country_long: { type: 'string' },
+ region: { type: 'string' },
+ city: { type: 'string' },
+ },
+ },
+ },
+ },
+ // we only use the short code currently
+ ( { body: { country_short } } ) => [ [ 'geo', country_short ] ]
+ ),
+ }
+ );
diff --git a/client/state/data-layer/http-data/index.js b/client/state/data-layer/http-data/index.js
index 6c3117eb59c61..d08303087006f 100644
--- a/client/state/data-layer/http-data/index.js
+++ b/client/state/data-layer/http-data/index.js
@@ -105,8 +105,10 @@ const parseResponse = ( data, fromApi ) => {
};
const onSuccess = ( action, apiData ) => {
- const fromApi = 'function' === typeof action.fromApi && action.fromApi();
- const [ error, data ] = fromApi ? parseResponse( apiData, fromApi ) : [ undefined, [] ];
+ const [ error, data ] =
+ 'function' === typeof action.fromApi
+ ? parseResponse( apiData, action.fromApi )
+ : [ undefined, [] ];
if ( undefined !== error ) {
return onError( action, error );
diff --git a/client/state/geo/actions.js b/client/state/geo/actions.js
deleted file mode 100644
index ea141ed27478b..0000000000000
--- a/client/state/geo/actions.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/** @format */
-
-/**
- * Internal dependencies
- */
-
-import request from 'superagent';
-import {
- GEO_RECEIVE,
- GEO_REQUEST,
- GEO_REQUEST_FAILURE,
- GEO_REQUEST_SUCCESS,
-} from 'state/action-types';
-
-/**
- * Constants
- */
-export const GEO_ENDPOINT = 'https://public-api.wordpress.com/geo/';
-
-/**
- * Returns an action object used in signalling that the current browser IP
- * geolocation has been received.
- *
- * @param {Object} geo Geolocation data
- * @return {Object} Action object
- */
-export function receiveGeo( geo ) {
- return {
- type: GEO_RECEIVE,
- geo,
- };
-}
-
-/**
- * Returns a function which, when invoked, triggers a network request to fetch
- * browser IP geolocation.
- *
- * @return {Function} Action thunk
- */
-export function requestGeo() {
- return dispatch => {
- dispatch( { type: GEO_REQUEST } );
-
- return request
- .get( GEO_ENDPOINT )
- .then( ( { body: geo } ) => {
- dispatch( { type: GEO_REQUEST_SUCCESS } );
- dispatch( receiveGeo( geo ) );
- } )
- .catch( error => {
- dispatch( {
- type: GEO_REQUEST_FAILURE,
- error,
- } );
- } );
- };
-}
diff --git a/client/state/geo/reducer.js b/client/state/geo/reducer.js
deleted file mode 100644
index 4e7b9e5ac41f9..0000000000000
--- a/client/state/geo/reducer.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/** @format */
-
-/**
- * Internal dependencies
- */
-
-import {
- GEO_RECEIVE,
- GEO_REQUEST,
- GEO_REQUEST_FAILURE,
- GEO_REQUEST_SUCCESS,
-} from 'state/action-types';
-import { combineReducers, createReducer } from 'state/utils';
-import { geoSchema } from './schema';
-
-/**
- * Returns the updated requesting state after an action has been dispatched.
- * Requesting state tracks whether a geolocation request is in progress.
- *
- * @param {Object} state Current state
- * @param {Object} action Action object
- * @return {Object} Updated state
- */
-export const requesting = createReducer( false, {
- [ GEO_REQUEST ]: () => true,
- [ GEO_REQUEST_FAILURE ]: () => false,
- [ GEO_REQUEST_SUCCESS ]: () => false,
-} );
-
-/**
- * Returns the updated requesting state after an action has been dispatched.
- * Requesting state tracks current browser IP geolocation.
- *
- * @param {?Object} state Current state
- * @param {Object} action Action object
- * @return {?Object} Updated state
- */
-export const geo = createReducer(
- null,
- {
- [ GEO_RECEIVE ]: ( state, action ) => action.geo,
- },
- geoSchema
-);
-
-export default combineReducers( {
- requesting,
- geo,
-} );
diff --git a/client/state/geo/schema.js b/client/state/geo/schema.js
deleted file mode 100644
index 62299916d68d6..0000000000000
--- a/client/state/geo/schema.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/** @format */
-export const geoSchema = {
- type: [ 'object', 'null' ],
- properties: {
- latitude: { type: 'string' },
- longitude: { type: 'string' },
- country_short: { type: 'string' },
- country_long: { type: 'string' },
- region: { type: 'string' },
- city: { type: 'string' },
- },
-};
diff --git a/client/state/geo/selectors.js b/client/state/geo/selectors.js
deleted file mode 100644
index 3dd7f151b703c..0000000000000
--- a/client/state/geo/selectors.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/** @format */
-
-/**
- * External dependencies
- */
-
-import { get } from 'lodash';
-
-/**
- * Returns whether a browser IP geolocation request is in progress.
- *
- * @param {Object} state Global state tree
- * @return {Boolean} Whether request is in progress
- */
-export function isRequestingGeo( state ) {
- return state.geo.requesting;
-}
-
-/**
- * Returns the current browser IP geolocation data.
- *
- * @param {Object} state Global state tree
- * @return {?Object} Current browser IP geolocation data
- */
-export function getGeo( state ) {
- return state.geo.geo;
-}
-
-/**
- * Returns the current browser IP geolocation full country name.
- *
- * @param {Object} state Global state tree
- * @return {?String} Current browser IP geolocation data
- */
-export function getGeoCountry( state ) {
- return get( getGeo( state ), 'country_long', null );
-}
-
-/**
- * Returns the current browser IP geolocation abbreviated country name.
- *
- * @param {Object} state Global state tree
- * @return {?String} Current browser IP geolocation short country name
- */
-export function getGeoCountryShort( state ) {
- return get( getGeo( state ), 'country_short', null );
-}
diff --git a/client/state/geo/test/actions.js b/client/state/geo/test/actions.js
deleted file mode 100644
index d47d74c63f889..0000000000000
--- a/client/state/geo/test/actions.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/** @format */
-/**
- * External dependencies
- */
-import { expect } from 'chai';
-import { match } from 'sinon';
-
-/**
- * Internal dependencies
- */
-import { receiveGeo, requestGeo } from '../actions';
-import {
- GEO_RECEIVE,
- GEO_REQUEST,
- GEO_REQUEST_SUCCESS,
- GEO_REQUEST_FAILURE,
-} from 'state/action-types';
-import useNock from 'test/helpers/use-nock';
-import { useSandbox } from 'test/helpers/use-sinon';
-
-describe( 'actions', () => {
- let spy;
- useSandbox( sandbox => ( spy = sandbox.spy() ) );
-
- describe( 'receiveGeo()', () => {
- test( 'should return an action object', () => {
- const action = receiveGeo( {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- } );
-
- expect( action ).to.eql( {
- type: GEO_RECEIVE,
- geo: {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- },
- } );
- } );
- } );
-
- describe( 'requestGeo()', () => {
- test( 'should dispatch fetch action when thunk triggered', () => {
- requestGeo()( spy );
-
- expect( spy ).to.have.been.calledWith( {
- type: GEO_REQUEST,
- } );
- } );
-
- describe( 'success', () => {
- useNock( nock => {
- nock( 'https://public-api.wordpress.com:443' )
- .persist()
- .get( '/geo/' )
- .reply( 200, {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- } );
- } );
-
- test( 'should dispatch receive action when request completes', () => {
- return requestGeo()( spy ).then( () => {
- expect( spy ).to.have.been.calledWith(
- receiveGeo( {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- } )
- );
- } );
- } );
-
- test( 'should dispatch request success action when request completes', () => {
- return requestGeo()( spy ).then( () => {
- expect( spy ).to.have.been.calledWith( {
- type: GEO_REQUEST_SUCCESS,
- } );
- } );
- } );
- } );
-
- describe( 'failure', () => {
- useNock( nock => {
- nock( 'https://public-api.wordpress.com:443' )
- .persist()
- .get( '/geo/' )
- .reply( 500 );
- } );
-
- test( 'should dispatch fail action when request fails', () => {
- return requestGeo()( spy ).then( () => {
- expect( spy ).to.have.been.calledWith( {
- type: GEO_REQUEST_FAILURE,
- error: match( { message: 'Internal Server Error' } ),
- } );
- } );
- } );
- } );
- } );
-} );
diff --git a/client/state/geo/test/reducer.js b/client/state/geo/test/reducer.js
deleted file mode 100644
index 512cdfe47a95a..0000000000000
--- a/client/state/geo/test/reducer.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/** @format */
-
-/**
- * External dependencies
- */
-import { expect } from 'chai';
-import deepFreeze from 'deep-freeze';
-
-/**
- * Internal dependencies
- */
-import reducer, { requesting, geo } from '../reducer';
-import {
- GEO_RECEIVE,
- GEO_REQUEST,
- GEO_REQUEST_FAILURE,
- GEO_REQUEST_SUCCESS,
- DESERIALIZE,
-} from 'state/action-types';
-import { useSandbox } from 'test/helpers/use-sinon';
-
-describe( 'reducer', () => {
- useSandbox( sandbox => sandbox.stub( console, 'warn' ) );
-
- test( 'should include expected keys in return value', () => {
- expect( reducer( undefined, {} ) ).to.have.keys( [ 'requesting', 'geo' ] );
- } );
-
- describe( 'requesting()', () => {
- test( 'should default to false', () => {
- const state = requesting( undefined, {} );
-
- expect( state ).to.be.false;
- } );
-
- test( 'should set site ID to true value if request in progress', () => {
- const state = requesting( undefined, {
- type: GEO_REQUEST,
- } );
-
- expect( state ).to.eql( true );
- } );
-
- test( 'should set site ID to false if request succeeds', () => {
- const state = requesting( true, {
- type: GEO_REQUEST_SUCCESS,
- } );
-
- expect( state ).to.eql( false );
- } );
-
- test( 'should set site ID to false if request fails', () => {
- const state = requesting( true, {
- type: GEO_REQUEST_FAILURE,
- } );
-
- expect( state ).to.eql( false );
- } );
- } );
-
- describe( 'geo()', () => {
- test( 'should default to null', () => {
- const state = geo( undefined, {} );
-
- expect( state ).to.be.null;
- } );
-
- test( 'should track received geo data', () => {
- const state = geo( undefined, {
- type: GEO_RECEIVE,
- geo: {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- },
- } );
-
- expect( state ).to.eql( {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- } );
- } );
-
- test( 'should load valid persisted state', () => {
- const original = deepFreeze( {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- } );
- const state = geo( original, { type: DESERIALIZE } );
-
- expect( state ).to.eql( {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- } );
- } );
-
- test( 'should not load invalid persisted state', () => {
- const original = deepFreeze( {
- country_short: true,
- } );
- const state = geo( original, { type: DESERIALIZE } );
-
- expect( state ).to.be.null;
- } );
- } );
-} );
diff --git a/client/state/geo/test/selectors.js b/client/state/geo/test/selectors.js
deleted file mode 100644
index 7e46f681d5329..0000000000000
--- a/client/state/geo/test/selectors.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/** @format */
-
-/**
- * External dependencies
- */
-import { expect } from 'chai';
-
-/**
- * Internal dependencies
- */
-import { isRequestingGeo, getGeo, getGeoCountry, getGeoCountryShort } from '../selectors';
-
-describe( 'selectors', () => {
- describe( 'isRequestingGeo()', () => {
- test( 'should return requesting state', () => {
- const isRequesting = isRequestingGeo( {
- geo: {
- requesting: true,
- },
- } );
-
- expect( isRequesting ).to.be.true;
- } );
- } );
-
- describe( 'getGeo()', () => {
- test( 'should return geo data state', () => {
- const geo = getGeo( {
- geo: {
- geo: {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- },
- },
- } );
-
- expect( geo ).to.eql( {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- } );
- } );
- } );
-
- describe( 'getGeoCountry()', () => {
- test( 'should return null if no geo data state', () => {
- const country = getGeoCountry( {
- geo: {
- geo: null,
- },
- } );
-
- expect( country ).to.be.null;
- } );
-
- test( 'should return full country name of geo data state', () => {
- const country = getGeoCountry( {
- geo: {
- geo: {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- },
- },
- } );
-
- expect( country ).to.equal( 'United States' );
- } );
- } );
-
- describe( 'getGeoCountryShort()', () => {
- test( 'should return null if no geo data state', () => {
- const country = getGeoCountryShort( {
- geo: {
- geo: null,
- },
- } );
-
- expect( country ).to.be.null;
- } );
-
- test( 'should return abbreviated country name of geo data state', () => {
- const country = getGeoCountryShort( {
- geo: {
- geo: {
- latitude: '39.36006',
- longitude: '-84.30994',
- country_short: 'US',
- country_long: 'United States',
- region: 'Ohio',
- city: 'Mason',
- },
- },
- } );
-
- expect( country ).to.equal( 'US' );
- } );
- } );
-} );
diff --git a/client/state/index.js b/client/state/index.js
index dea22121fbee2..64147c1912611 100644
--- a/client/state/index.js
+++ b/client/state/index.js
@@ -40,7 +40,6 @@ import currentUser from './current-user/reducer';
import { reducer as dataRequests } from './data-layer/wpcom-http/utils';
import documentHead from './document-head/reducer';
import domains from './domains/reducer';
-import geo from './geo/reducer';
import googleAppsUsers from './google-apps-users/reducer';
import googleMyBusiness from './google-my-business/reducer';
import help from './help/reducer';
@@ -131,7 +130,6 @@ const reducers = {
domains,
extensions,
form,
- geo,
googleAppsUsers,
googleMyBusiness,
happinessEngineers,
diff --git a/client/state/selectors/get-current-user-payment-methods.js b/client/state/selectors/get-current-user-payment-methods.js
index e554ce5880ab5..21293ca47111c 100644
--- a/client/state/selectors/get-current-user-payment-methods.js
+++ b/client/state/selectors/get-current-user-payment-methods.js
@@ -10,7 +10,7 @@ import { lowerCase, upperCase } from 'lodash';
* Internal dependencies
*/
import { getCurrentUserLocale } from 'state/current-user/selectors';
-import { getGeoCountryShort } from 'state/geo/selectors';
+import { requestGeoLocation } from 'state/data-layer/http-data/getters';
/**
* Constants
@@ -44,7 +44,7 @@ const paymentMethods = {
* @return {Array} Preferred payment methods
*/
export default function getCurrentUserPaymentMethods( state ) {
- const countryCode = getGeoCountryShort( state );
+ const countryCode = requestGeoLocation().data;
const wpcomLang = getCurrentUserLocale( state );
const generatedLocale = lowerCase( wpcomLang ) + '-' + upperCase( countryCode );