Skip to content

Commit

Permalink
Merge pull request #208 from viatrix/89-preferred-place-locale
Browse files Browse the repository at this point in the history
Set preferredPlace based on locality from locale. Implements #89
  • Loading branch information
pleary authored Nov 24, 2020
2 parents 8eaa07e + 36c9a51 commit 12f5f0f
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 2 deletions.
37 changes: 35 additions & 2 deletions lib/inaturalist_api.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require( "intl" );
const _ = require( "lodash" );
const jwt = require( "jsonwebtoken" );
const fs = require( "fs" );
Expand Down Expand Up @@ -666,8 +667,40 @@ InaturalistAPI.lookupPlaceMiddleware = ( req, res, next ) => {
};

InaturalistAPI.lookupPreferredPlaceMiddleware = ( req, res, next ) => {
InaturalistAPI.lookupInstanceMiddleware( req, res, next,
"preferred_place_id", Place.findByID, "preferredPlace" );
if ( req.query.preferred_place_id ) {
return void InaturalistAPI.lookupInstanceMiddleware( req, res, next,
"preferred_place_id", Place.findByID, "preferredPlace" );
}
// lookup by locality code from locale
let locale = req.userSession ? req.userSession.locale : null;
if ( req.query.locale ) {
( { locale } = req.query );
}
if ( locale ) {
let localeObj;
try {
localeObj = new Intl.Locale( locale );
} catch ( err ) {
// continue if locale is invalid
return void next( );
}
const localeRegionCode = localeObj.region;
if ( !localeRegionCode ) {
return void next( );
}
// lookup the place by code and admin-level = country
return void Place.findByLocaleCode( localeRegionCode ).then( obj => {
// no error if none of the instances exist
// locale codes are not always same as country codes
if ( _.isEmpty( obj ) ) {
return void next( );
}
req.inat = req.inat || { };
req.inat.preferredPlace = obj;
return void next( );
} ).catch( next );
}
next( );
};

InaturalistAPI.lookupUnobservedByUserMiddleware = ( req, res, next ) => {
Expand Down
17 changes: 17 additions & 0 deletions lib/models/place.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ const Place = class Place extends Model {
return response.hits.hits[0] ? response.hits.hits[0]._source : null;
}

static async findByLocaleCode( code ) {
const { rows } = await pgClient.connection.query( "SELECT id, name, ancestry FROM "
+ "places WHERE UPPER(code) = $1 AND admin_level = 0", [code] );
if ( !rows.length ) {
return null;
}
const result = rows[0];
// transform ancestry field to ancestor_place_ids
let ancestorPlaceIds = null;
if ( result.ancestry ) {
ancestorPlaceIds = result.ancestry ? result.ancestry.split( "/" ).map( str => parseInt( str, 10 ) ) : [];
ancestorPlaceIds.push( result.id );
}
const response = { id: result.id, name: result.name, ancestor_place_ids: ancestorPlaceIds };
return response;
}

static async assignToObject( object ) {
const ids = _.keys( object );
if ( ids.length === 0 ) { return; }
Expand Down
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"handlebars": "^4.7.6",
"hapi-joi-to-swagger": "github:inaturalist/hapi-joi-to-swagger#0ec177ccc9f8306f6fbcc7066174313e593c0600",
"inaturalistjs": "github:inaturalist/inaturalistjs#bfce66c2927a756d654454362bc67fc3892ba7a3",
"intl": "^1.2.5",
"jsonwebtoken": "^8.3.0",
"lodash": "^4.17.15",
"lodash.merge": "^4.6.2",
Expand Down
13 changes: 13 additions & 0 deletions schema/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,19 @@
"name": "a-place-in-a-place",
"display_name": "A Place In A Place",
"ancestry": "432/433"
},
{
"id": 511,
"name": "locale-place",
"code": "LP",
"admin_level": 0,
"ancestry": "111"
},
{
"id": 512,
"name": "locale-place-admin-level-1",
"code": "LPA",
"admin_level": 1
}
],
"preferences": [
Expand Down
34 changes: 34 additions & 0 deletions test/inaturalist_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,38 @@ describe( "InaturalistAPI", ( ) => {
} );
} );
} );

describe( "lookupPreferredPlaceMiddleware", ( ) => {
it( "looks up preferred_place by preferred_place_id", done => {
const req = { query: { preferred_place_id: 1, locale: "zh-LP"}, inat: {} };
InaturalistAPI.lookupPreferredPlaceMiddleware( req, null, () => {
expect( req.inat.preferredPlace.id ).to.eq( 1 );
done( );
} );
} );

it( "looks up preferred_place by locale", done => {
const req = { query: { locale: "zh-LP" }, inat: {} };
InaturalistAPI.lookupPreferredPlaceMiddleware( req, null, () => {
expect( req.inat.preferredPlace.id ).to.eq( 511 );
done( );
} );
} );

it( "does not set preferred_place if locale is malformed", done => {
const req = { query: { locale: "zh-LP-LP" }, inat: {} };
InaturalistAPI.lookupPreferredPlaceMiddleware( req, null, () => {
expect( req.inat.preferredPlace ).to.be.undefined;
done( );
} );
} );

it( "does not set preferred_place if country is not found", done => {
const req = { query: { locale: "zh-LPB" } };
InaturalistAPI.lookupPreferredPlaceMiddleware( req, null, () => {
expect( req.inat ).to.be.undefined;
done( );
} );
} );
} );
} );
21 changes: 21 additions & 0 deletions test/models/place.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,27 @@ describe( "Place", ( ) => {
} );
} );

describe( "findByLocaleCode", ( ) => {
it( "returns a place given a code", async ( ) => {
const p = await Place.findByLocaleCode( "LP" );
expect( p.id ).to.eq( 511 );
expect( p.name ).to.eq( "locale-place" );
expect( p.ancestor_place_ids.length ).to.eq( 2 );
expect( p.ancestor_place_ids[0] ).to.eq( 111 );
expect( p.ancestor_place_ids[1] ).to.eq( 511 );
} );

it( "returns null if admin_level is not country", async ( ) => {
const p = await Place.findByLocaleCode( "LPA" );
expect( p ).to.eq( null );
} );

it( "returns null given an unknown code", async ( ) => {
const p = await Place.findByLocaleCode( "US" );
expect( p ).to.eq( null );
} );
} );

describe( "assignToObject", ( ) => {
it( "assigns place instances to objects", done => {
const o = { 1: { }, 123: { }, 432: { } };
Expand Down

0 comments on commit 12f5f0f

Please sign in to comment.