mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-09 09:47:28 +03:00
Take into consideration types of visits when increasing tags visits
This commit is contained in:
parent
927ab76dbd
commit
1d6464fefb
2 changed files with 91 additions and 6 deletions
|
@ -8,7 +8,7 @@ import type { createShortUrl } from '../../short-urls/reducers/shortUrlCreation'
|
||||||
import { supportedFeatures } from '../../utils/helpers/features';
|
import { supportedFeatures } from '../../utils/helpers/features';
|
||||||
import { createAsyncThunk } from '../../utils/helpers/redux';
|
import { createAsyncThunk } from '../../utils/helpers/redux';
|
||||||
import { createNewVisits } from '../../visits/reducers/visitCreation';
|
import { createNewVisits } from '../../visits/reducers/visitCreation';
|
||||||
import type { CreateVisit, Stats } from '../../visits/types';
|
import type { CreateVisit } from '../../visits/types';
|
||||||
import type { TagStats } from '../data';
|
import type { TagStats } from '../data';
|
||||||
import { tagDeleted } from './tagDelete';
|
import { tagDeleted } from './tagDelete';
|
||||||
import { tagEdited } from './tagEdit';
|
import { tagEdited } from './tagEdit';
|
||||||
|
@ -39,7 +39,8 @@ const initialState: TagsList = {
|
||||||
error: false,
|
error: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
type TagIncrease = [string, number];
|
type TagIncreaseRecord = Record<string, { bots: number; nonBots: number }>;
|
||||||
|
type TagIncrease = [string, { bots: number; nonBots: number }];
|
||||||
|
|
||||||
const renameTag = (oldName: string, newName: string) => (tag: string) => (tag === oldName ? newName : tag);
|
const renameTag = (oldName: string, newName: string) => (tag: string) => (tag === oldName ? newName : tag);
|
||||||
const rejectTag = (tags: string[], tagToReject: string) => reject((tag) => tag === tagToReject, tags);
|
const rejectTag = (tags: string[], tagToReject: string) => reject((tag) => tag === tagToReject, tags);
|
||||||
|
@ -48,21 +49,34 @@ const increaseVisitsForTags = (tags: TagIncrease[], stats: TagsStatsMap) => tags
|
||||||
return theStats;
|
return theStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { bots, nonBots } = increase;
|
||||||
const tagStats = theStats[tag];
|
const tagStats = theStats[tag];
|
||||||
|
|
||||||
// TODO take into consideration bots, nonBots and total
|
|
||||||
return {
|
return {
|
||||||
...theStats,
|
...theStats,
|
||||||
[tag]: {
|
[tag]: {
|
||||||
...tagStats,
|
...tagStats,
|
||||||
visitsCount: tagStats.visitsCount + increase,
|
visitsSummary: tagStats.visitsSummary && {
|
||||||
|
total: tagStats.visitsSummary.total + bots + nonBots,
|
||||||
|
bots: tagStats.visitsSummary.bots + bots,
|
||||||
|
nonBots: tagStats.visitsSummary.nonBots + nonBots,
|
||||||
|
},
|
||||||
|
visitsCount: tagStats.visitsCount + bots + nonBots,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}, { ...stats });
|
}, { ...stats });
|
||||||
const calculateVisitsPerTag = (createdVisits: CreateVisit[]): TagIncrease[] => Object.entries(
|
const calculateVisitsPerTag = (createdVisits: CreateVisit[]): TagIncrease[] => Object.entries(
|
||||||
createdVisits.reduce<Stats>((acc, { shortUrl }) => {
|
createdVisits.reduce<TagIncreaseRecord>((acc, { shortUrl, visit }) => {
|
||||||
shortUrl?.tags.forEach((tag) => {
|
shortUrl?.tags.forEach((tag) => {
|
||||||
acc[tag] = (acc[tag] || 0) + 1;
|
if (!acc[tag]) {
|
||||||
|
acc[tag] = { bots: 0, nonBots: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visit.potentialBot) {
|
||||||
|
acc[tag].bots += 1;
|
||||||
|
} else {
|
||||||
|
acc[tag].nonBots += 1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
|
|
|
@ -11,6 +11,8 @@ import {
|
||||||
listTags as listTagsCreator,
|
listTags as listTagsCreator,
|
||||||
tagsListReducerCreator,
|
tagsListReducerCreator,
|
||||||
} from '../../../src/tags/reducers/tagsList';
|
} from '../../../src/tags/reducers/tagsList';
|
||||||
|
import { createNewVisits } from '../../../src/visits/reducers/visitCreation';
|
||||||
|
import type { CreateVisit, Visit } from '../../../src/visits/types';
|
||||||
|
|
||||||
describe('tagsListReducer', () => {
|
describe('tagsListReducer', () => {
|
||||||
const state = (props: Partial<TagsList>) => Mock.of<TagsList>(props);
|
const state = (props: Partial<TagsList>) => Mock.of<TagsList>(props);
|
||||||
|
@ -118,6 +120,75 @@ describe('tagsListReducer', () => {
|
||||||
tags: expectedTags,
|
tags: expectedTags,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('increases amounts when visits are created', () => {
|
||||||
|
const createdVisits = [
|
||||||
|
Mock.of<CreateVisit>({
|
||||||
|
shortUrl: Mock.of<ShortUrl>({ tags: ['foo', 'bar'] }),
|
||||||
|
visit: Mock.of<Visit>({ potentialBot: true }),
|
||||||
|
}),
|
||||||
|
Mock.of<CreateVisit>({
|
||||||
|
shortUrl: Mock.of<ShortUrl>({ tags: ['foo', 'bar'] }),
|
||||||
|
visit: Mock.all<Visit>(),
|
||||||
|
}),
|
||||||
|
Mock.of<CreateVisit>({
|
||||||
|
shortUrl: Mock.of<ShortUrl>({ tags: ['bar'] }),
|
||||||
|
visit: Mock.all<Visit>(),
|
||||||
|
}),
|
||||||
|
Mock.of<CreateVisit>({
|
||||||
|
shortUrl: Mock.of<ShortUrl>({ tags: ['baz'] }),
|
||||||
|
visit: Mock.of<Visit>({ potentialBot: true }),
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
const tagStats = (total: number) => ({
|
||||||
|
shortUrlsCount: 1,
|
||||||
|
visitsCount: total,
|
||||||
|
visitsSummary: {
|
||||||
|
total,
|
||||||
|
nonBots: total - 10,
|
||||||
|
bots: 10,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const stateBefore = state({
|
||||||
|
stats: {
|
||||||
|
foo: tagStats(100),
|
||||||
|
bar: tagStats(200),
|
||||||
|
baz: tagStats(150),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(reducer(stateBefore, createNewVisits(createdVisits))).toEqual(expect.objectContaining({
|
||||||
|
stats: {
|
||||||
|
foo: {
|
||||||
|
shortUrlsCount: 1,
|
||||||
|
visitsCount: 100 + 2,
|
||||||
|
visitsSummary: {
|
||||||
|
total: 100 + 2,
|
||||||
|
nonBots: 90 + 1,
|
||||||
|
bots: 10 + 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
shortUrlsCount: 1,
|
||||||
|
visitsCount: 200 + 3,
|
||||||
|
visitsSummary: {
|
||||||
|
total: 200 + 3,
|
||||||
|
nonBots: 190 + 2,
|
||||||
|
bots: 10 + 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
baz: {
|
||||||
|
shortUrlsCount: 1,
|
||||||
|
visitsCount: 150 + 1,
|
||||||
|
visitsSummary: {
|
||||||
|
total: 150 + 1,
|
||||||
|
nonBots: 140,
|
||||||
|
bots: 10 + 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('filterTags', () => {
|
describe('filterTags', () => {
|
||||||
|
|
Loading…
Reference in a new issue