Refactored visits parser to be functional

This commit is contained in:
Alejandro Celaya 2018-08-24 23:55:53 +02:00
parent 4924f24e1a
commit 6d0753481d
3 changed files with 74 additions and 60 deletions

View file

@ -7,13 +7,21 @@ import Moment from 'react-moment'
import { connect } from 'react-redux'
import { Card, CardBody, CardHeader, UncontrolledTooltip } from 'reactstrap'
import DateInput from '../common/DateInput'
import visitsParser from '../visits/services/VisitsParser'
import {
processOsStats,
processBrowserStats,
processCountriesStats,
processReferrersStats,
} from '../visits/services/VisitsParser'
import { getShortUrlVisits } from './reducers/shortUrlVisits'
import './ShortUrlVisits.scss'
import MutedMessage from '../utils/MuttedMessage';
const defaultProps = {
visitsParser,
processOsStats,
processBrowserStats,
processCountriesStats,
processReferrersStats,
};
export class ShortUrlsVisits extends React.Component {
@ -34,7 +42,10 @@ export class ShortUrlsVisits extends React.Component {
const {
match: { params },
selectedServer,
visitsParser,
processOsStats,
processBrowserStats,
processCountriesStats,
processReferrersStats,
shortUrlVisits: { visits, loading, error, shortUrl }
} = this.props;
const serverUrl = selectedServer ? selectedServer.url : '';
@ -96,10 +107,10 @@ export class ShortUrlsVisits extends React.Component {
return (
<div className="row">
{renderGraphCard('Operating systems', visitsParser.processOsStats(visits), false)}
{renderGraphCard('Browsers', visitsParser.processBrowserStats(visits), false)}
{renderGraphCard('Countries', visitsParser.processCountriesStats(visits), true, 'Visits')}
{renderGraphCard('Referrers', visitsParser.processReferrersStats(visits), true, 'Visits')}
{renderGraphCard('Operating systems', processOsStats(visits), false)}
{renderGraphCard('Browsers', processBrowserStats(visits), false)}
{renderGraphCard('Countries', processCountriesStats(visits), true, 'Visits')}
{renderGraphCard('Referrers', processReferrersStats(visits), true, 'Visits')}
</div>
);
};
@ -173,4 +184,7 @@ export class ShortUrlsVisits extends React.Component {
ShortUrlsVisits.defaultProps = defaultProps;
export default connect(pick(['selectedServer', 'shortUrlVisits']), { getShortUrlVisits })(ShortUrlsVisits);
export default connect(
pick(['selectedServer', 'shortUrlVisits']),
{ getShortUrlVisits }
)(ShortUrlsVisits);

View file

@ -41,53 +41,48 @@ const extractDomain = url => {
return domain.split(':')[0];
};
export class VisitsParser {
processOsStats = visits =>
reduce(
(stats, visit) => {
const userAgent = visit.userAgent;
const os = isNil(userAgent) ? 'Others' : osFromUserAgent(userAgent);
return assoc(os, (stats[os] || 0) + 1, stats);
},
{},
visits,
);
export const processOsStats = visits =>
reduce(
(stats, visit) => {
const userAgent = visit.userAgent;
const os = isNil(userAgent) ? 'Others' : osFromUserAgent(userAgent);
return assoc(os, (stats[os] || 0) + 1, stats);
},
{},
visits,
);
processBrowserStats = visits =>
reduce(
(stats, visit) => {
const userAgent = visit.userAgent;
const browser = isNil(userAgent) ? 'Others' : browserFromUserAgent(userAgent);
return assoc(browser, (stats[browser] || 0) + 1, stats);
},
{},
visits,
);
export const processBrowserStats = visits =>
reduce(
(stats, visit) => {
const userAgent = visit.userAgent;
const browser = isNil(userAgent) ? 'Others' : browserFromUserAgent(userAgent);
return assoc(browser, (stats[browser] || 0) + 1, stats);
},
{},
visits,
);
processReferrersStats = visits =>
reduce(
(stats, visit) => {
const notHasDomain = isNil(visit.referer) || isEmpty(visit.referer);
const domain = notHasDomain ? 'Unknown' : extractDomain(visit.referer);
return assoc(domain, (stats[domain]|| 0) + 1, stats);
},
{},
visits,
);
export const processReferrersStats = visits =>
reduce(
(stats, visit) => {
const notHasDomain = isNil(visit.referer) || isEmpty(visit.referer);
const domain = notHasDomain ? 'Unknown' : extractDomain(visit.referer);
return assoc(domain, (stats[domain]|| 0) + 1, stats);
},
{},
visits,
);
processCountriesStats = visits =>
reduce(
(stats, { visitLocation }) => {
const notHasCountry = isNil(visitLocation)
|| isNil(visitLocation.countryName)
|| isEmpty(visitLocation.countryName);
const country = notHasCountry ? 'Unknown' : visitLocation.countryName;
return assoc(country, (stats[country]|| 0) + 1, stats);
},
{},
visits,
);
}
const visitsParser = new VisitsParser();
export default visitsParser;
export const processCountriesStats = visits =>
reduce(
(stats, { visitLocation }) => {
const notHasCountry = isNil(visitLocation)
|| isNil(visitLocation.countryName)
|| isEmpty(visitLocation.countryName);
const country = notHasCountry ? 'Unknown' : visitLocation.countryName;
return assoc(country, (stats[country]|| 0) + 1, stats);
},
{},
visits,
);

View file

@ -1,4 +1,9 @@
import visitsParser from '../../../src/visits/services/VisitsParser';
import {
processOsStats,
processBrowserStats,
processReferrersStats,
processCountriesStats,
} from '../../../src/visits/services/VisitsParser';
describe('VisitsParser', () => {
const visits = [
@ -36,7 +41,7 @@ describe('VisitsParser', () => {
describe('processOsStats', () => {
it('properly parses OS stats', () => {
expect(visitsParser.processOsStats(visits)).toEqual({
expect(processOsStats(visits)).toEqual({
'Linux': 3,
'Windows': 1,
'MacOS': 1,
@ -46,7 +51,7 @@ describe('VisitsParser', () => {
describe('processBrowserStats', () => {
it('properly parses browser stats', () => {
expect(visitsParser.processBrowserStats(visits)).toEqual({
expect(processBrowserStats(visits)).toEqual({
'Firefox': 2,
'Chrome': 2,
'Opera': 1,
@ -56,7 +61,7 @@ describe('VisitsParser', () => {
describe('processReferrersStats', () => {
it('properly parses referrer stats', () => {
expect(visitsParser.processReferrersStats(visits)).toEqual({
expect(processReferrersStats(visits)).toEqual({
'Unknown': 2,
'google.com': 2,
'm.facebook.com': 1,
@ -66,7 +71,7 @@ describe('VisitsParser', () => {
describe('processCountriesStats', () => {
it('properly parses countries stats', () => {
expect(visitsParser.processCountriesStats(visits)).toEqual({
expect(processCountriesStats(visits)).toEqual({
'Spain': 3,
'United States': 1,
'Unknown': 1,