diff --git a/src/visits/ShortUrlVisits.js b/src/visits/ShortUrlVisits.js index 589dbb78..1a057279 100644 --- a/src/visits/ShortUrlVisits.js +++ b/src/visits/ShortUrlVisits.js @@ -87,8 +87,8 @@ const ShortUrlVisits = ({ processStatsFromVisits, normalizeVisits }, OpenMapModa const showTableControls = !loading && visits.length > 0; const normalizedVisits = useMemo(() => normalizeVisits(visits), [ visits ]); const { os, browsers, referrers, countries, cities, citiesForMap } = useMemo( - () => processStatsFromVisits(visits), - [ visits ] + () => processStatsFromVisits(normalizedVisits), + [ normalizedVisits ] ); const mapLocations = values(citiesForMap); diff --git a/src/visits/services/VisitsParser.js b/src/visits/services/VisitsParser.js index 25db20d8..2ebd5262 100644 --- a/src/visits/services/VisitsParser.js +++ b/src/visits/services/VisitsParser.js @@ -1,60 +1,52 @@ -import { isEmpty, isNil, map } from 'ramda'; +import { isNil, map } from 'ramda'; import { browserFromUserAgent, extractDomain, osFromUserAgent } from '../../utils/helpers/visits'; +import { hasValue } from '../../utils/utils'; -const visitLocationHasProperty = (visitLocation, propertyName) => - !isNil(visitLocation) - && !isNil(visitLocation[propertyName]) - && !isEmpty(visitLocation[propertyName]); - -const updateOsStatsForVisit = (osStats, { userAgent }) => { - const os = osFromUserAgent(userAgent); +const visitHasProperty = (visit, propertyName) => !isNil(visit) && hasValue(visit[propertyName]); +const updateOsStatsForVisit = (osStats, { os }) => { osStats[os] = (osStats[os] || 0) + 1; }; -const updateBrowsersStatsForVisit = (browsersStats, { userAgent }) => { - const browser = browserFromUserAgent(userAgent); - +const updateBrowsersStatsForVisit = (browsersStats, { browser }) => { browsersStats[browser] = (browsersStats[browser] || 0) + 1; }; -const updateReferrersStatsForVisit = (referrersStats, { referer }) => { - const domain = extractDomain(referer); - +const updateReferrersStatsForVisit = (referrersStats, { referer: domain }) => { referrersStats[domain] = (referrersStats[domain] || 0) + 1; }; -const updateLocationsStatsForVisit = (propertyName) => (stats, { visitLocation }) => { - const hasLocationProperty = visitLocationHasProperty(visitLocation, propertyName); - const value = hasLocationProperty ? visitLocation[propertyName] : 'Unknown'; +const updateLocationsStatsForVisit = (propertyName) => (stats, visit) => { + const hasLocationProperty = visitHasProperty(visit, propertyName); + const value = hasLocationProperty ? visit[propertyName] : 'Unknown'; stats[value] = (stats[value] || 0) + 1; }; -const updateCountriesStatsForVisit = updateLocationsStatsForVisit('countryName'); -const updateCitiesStatsForVisit = updateLocationsStatsForVisit('cityName'); +const updateCountriesStatsForVisit = updateLocationsStatsForVisit('country'); +const updateCitiesStatsForVisit = updateLocationsStatsForVisit('city'); -const updateCitiesForMapForVisit = (citiesForMapStats, { visitLocation }) => { - if (!visitLocationHasProperty(visitLocation, 'cityName')) { +const updateCitiesForMapForVisit = (citiesForMapStats, visit) => { + if (!visitHasProperty(visit, 'city') || visit.city === 'Unknown') { return; } - const { cityName, latitude, longitude } = visitLocation; - const currentCity = citiesForMapStats[cityName] || { - cityName, + const { city, latitude, longitude } = visit; + const currentCity = citiesForMapStats[city] || { + cityName: city, count: 0, latLong: [ parseFloat(latitude), parseFloat(longitude) ], }; currentCity.count++; - citiesForMapStats[cityName] = currentCity; + citiesForMapStats[city] = currentCity; }; -export const processStatsFromVisits = (visits) => - visits.reduce( +export const processStatsFromVisits = (normalizedVisits) => + normalizedVisits.reduce( (stats, visit) => { - // We mutate the original object because it has a big side effect when large data sets are processed + // We mutate the original object because it has a big performance impact when large data sets are processed updateOsStatsForVisit(stats.os, visit); updateBrowsersStatsForVisit(stats.browsers, visit); updateReferrersStatsForVisit(stats.referrers, visit); @@ -74,4 +66,6 @@ export const normalizeVisits = map(({ userAgent, date, referer, visitLocation }) referer: extractDomain(referer), country: (visitLocation && visitLocation.countryName) || 'Unknown', city: (visitLocation && visitLocation.cityName) || 'Unknown', + latitude: visitLocation && visitLocation.latitude, + longitude: visitLocation && visitLocation.longitude, })); diff --git a/test/visits/services/VisitsParser.test.js b/test/visits/services/VisitsParser.test.js index a10eef13..3538be10 100644 --- a/test/visits/services/VisitsParser.test.js +++ b/test/visits/services/VisitsParser.test.js @@ -8,8 +8,8 @@ describe('VisitsParser', () => { visitLocation: { countryName: 'Spain', cityName: 'Zaragoza', - latitude: '123.45', - longitude: '-543.21', + latitude: 123.45, + longitude: -543.21, }, }, { @@ -18,8 +18,8 @@ describe('VisitsParser', () => { visitLocation: { countryName: 'United States', cityName: 'New York', - latitude: '1029', - longitude: '6758', + latitude: 1029, + longitude: 6758, }, }, { @@ -34,8 +34,8 @@ describe('VisitsParser', () => { visitLocation: { countryName: 'Spain', cityName: 'Zaragoza', - latitude: '123.45', - longitude: '-543.21', + latitude: 123.45, + longitude: -543.21, }, }, { @@ -47,7 +47,7 @@ describe('VisitsParser', () => { let stats; beforeAll(() => { - stats = processStatsFromVisits(visits); + stats = processStatsFromVisits(normalizeVisits(visits)); }); it('properly parses OS stats', () => { @@ -132,6 +132,8 @@ describe('VisitsParser', () => { country: 'Spain', city: 'Zaragoza', date: undefined, + latitude: 123.45, + longitude: -543.21, }, { browser: 'Firefox', @@ -140,6 +142,8 @@ describe('VisitsParser', () => { country: 'United States', city: 'New York', date: undefined, + latitude: 1029, + longitude: 6758, }, { browser: 'Chrome', @@ -148,6 +152,8 @@ describe('VisitsParser', () => { country: 'Spain', city: 'Unknown', date: undefined, + latitude: undefined, + longitude: undefined, }, { browser: 'Chrome', @@ -156,6 +162,8 @@ describe('VisitsParser', () => { country: 'Spain', city: 'Zaragoza', date: undefined, + latitude: 123.45, + longitude: -543.21, }, { browser: 'Opera', @@ -164,6 +172,8 @@ describe('VisitsParser', () => { country: 'Unknown', city: 'Unknown', date: undefined, + latitude: undefined, + longitude: undefined, }, ]); });