Skip to content

Commit 1741b54

Browse files
authored
RI-5335 Add free DB identifier in telemetry events (#4267)
- INSIGHTS_PANEL_OPENED - INSIGHTS_PANEL_CLOSED - EXPLORE_PANEL_TUTORIAL_OPENED - EXPLORE_PANEL_COMMAND_COPIED - EXPLORE_PANEL_COMMAND_RUN_CLICKED - EXPLORE_PANEL_LINK_CLICKED - TelemetryPageView.BROWSER_PAGE
1 parent 57ecf7f commit 1741b54

File tree

4 files changed

+131
-4
lines changed

4 files changed

+131
-4
lines changed

redisinsight/ui/src/pages/browser/BrowserPage.test.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { render, screen, fireEvent, mockedStore, cleanup, act, waitForEuiToolTip
66
import { KeyTypes } from 'uiSrc/constants'
77
import { RootState } from 'uiSrc/slices/store'
88
import { setSelectedKeyRefreshDisabled, toggleBrowserFullScreen } from 'uiSrc/slices/browser/keys'
9+
import { sendPageViewTelemetry, TelemetryPageView } from 'uiSrc/telemetry'
10+
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
911
import BrowserPage from './BrowserPage'
1012
import KeyList, { Props as KeyListProps } from './components/key-list/KeyList'
1113

@@ -77,12 +79,55 @@ const selectKey = (state: any, selectedKey: any, data?: any = {}) => {
7779
}))
7880
}
7981

82+
jest.mock('uiSrc/telemetry', () => ({
83+
...jest.requireActual('uiSrc/telemetry'),
84+
sendPageViewTelemetry: jest.fn(),
85+
}))
86+
87+
jest.mock('uiSrc/slices/instances/instances', () => ({
88+
...jest.requireActual('uiSrc/slices/instances/instances'),
89+
connectedInstanceSelector: jest.fn(),
90+
}))
8091
/**
8192
* BrowserPage tests
8293
*
8394
* @group component
8495
*/
8596

97+
const originalUseSelector = jest.requireActual('react-redux').useSelector
98+
99+
describe('BrowserPage', () => {
100+
const commonOptions = {
101+
id: 'instanceId',
102+
name: 'test',
103+
connectionType: 'CLUSTER',
104+
provider: 'RE_CLOUD',
105+
}
106+
107+
beforeAll(() => {
108+
(useSelector as jest.Mock).mockImplementation(originalUseSelector)
109+
})
110+
111+
it.each([true, false])('should call proper sendPageViewTelemetry when isFreeDb is %s', (isFreeDb) => {
112+
const sendPageViewTelemetryMock = jest.fn();
113+
(sendPageViewTelemetry as jest.Mock).mockImplementation(() => sendPageViewTelemetryMock);
114+
(connectedInstanceSelector as jest.Mock).mockImplementation(() => ({
115+
...commonOptions,
116+
isFreeDb,
117+
}))
118+
119+
render(<BrowserPage />)
120+
121+
expect(sendPageViewTelemetry).toBeCalledWith({
122+
name: TelemetryPageView.BROWSER_PAGE,
123+
eventData: {
124+
databaseId: 'instanceId',
125+
isFree: isFreeDb,
126+
},
127+
})
128+
})
129+
})
130+
86131
describe('KeyDetailsHeader', () => {
87132
beforeAll(() => {
88133
KeyList.mockImplementation(mockKeyList)

redisinsight/ui/src/pages/browser/BrowserPage.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const isOneSideMode = (isInsightsOpen: boolean) =>
6161
const BrowserPage = () => {
6262
const { instanceId } = useParams<{ instanceId: string }>()
6363

64-
const { name: connectedInstanceName, db = 0 } = useSelector(connectedInstanceSelector)
64+
const { name: connectedInstanceName, db = 0, isFreeDb } = useSelector(connectedInstanceSelector)
6565
const {
6666
panelSizes,
6767
keyList: { selectedKey: selectedKeyContext },
@@ -154,7 +154,8 @@ const BrowserPage = () => {
154154
sendPageViewTelemetry({
155155
name: TelemetryPageView.BROWSER_PAGE,
156156
eventData: {
157-
databaseId: instanceId
157+
databaseId: instanceId,
158+
isFree: isFreeDb,
158159
}
159160
})
160161
setIsPageViewSent(true)

redisinsight/ui/src/telemetry/telemetryUtils.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,27 @@ export const getProviderData = (dbId: string): {
3535
return { provider, serverName }
3636
}
3737

38+
const FREE_DB_IDENTIFIER_TELEMETRY_EVENTS = [
39+
TelemetryEvent.INSIGHTS_PANEL_OPENED,
40+
TelemetryEvent.INSIGHTS_PANEL_CLOSED,
41+
TelemetryEvent.EXPLORE_PANEL_TUTORIAL_OPENED,
42+
TelemetryEvent.EXPLORE_PANEL_COMMAND_COPIED,
43+
TelemetryEvent.EXPLORE_PANEL_COMMAND_RUN_CLICKED,
44+
TelemetryEvent.EXPLORE_PANEL_LINK_CLICKED,
45+
]
46+
47+
const getFreeDbFlag = (
48+
event: TelemetryEvent,
49+
freeDbEvents: TelemetryEvent[] = FREE_DB_IDENTIFIER_TELEMETRY_EVENTS
50+
): { isFree?: boolean } => {
51+
if (freeDbEvents.includes(event)) {
52+
const state = get(store.getState(), 'connections.instances.connectedInstance')
53+
return state ? { isFree: state.isFreeDb } : {}
54+
}
55+
56+
return {}
57+
}
58+
3859
const TELEMETRY_EMPTY_VALUE = 'none'
3960

4061
const sendEventTelemetry = async ({ event, eventData = {}, traits = {} }: ITelemetrySendEvent) => {
@@ -48,8 +69,11 @@ const sendEventTelemetry = async ({ event, eventData = {}, traits = {} }: ITelem
4869
if (eventData.databaseId) {
4970
providerData = getProviderData(eventData.databaseId)
5071
}
72+
73+
const freeDbIdentifier = getFreeDbFlag(event)
74+
5175
await apiService.post(`${ApiEndpoints.ANALYTICS_SEND_EVENT}`,
52-
{ event, eventData: { ...providerData, ...eventData }, traits })
76+
{ event, eventData: { ...providerData, ...eventData, ...freeDbIdentifier }, traits })
5377
} catch (e) {
5478
// continue regardless of error
5579
}
@@ -224,4 +248,5 @@ export {
224248
getAdditionalAddedEventData,
225249
getMatchType,
226250
getRedisModulesSummary,
251+
getFreeDbFlag,
227252
}

redisinsight/ui/src/telemetry/tests/telemetryUtils.spec.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { getRedisModulesSummary } from '../telemetryUtils'
1+
import { RootState, store } from 'uiSrc/slices/store'
2+
import { TelemetryEvent } from '../events'
3+
import { getRedisModulesSummary, getFreeDbFlag } from '../telemetryUtils'
24

35
const DEFAULT_SUMMARY = Object.freeze(
46
{
@@ -72,3 +74,57 @@ describe('getRedisModulesSummary', () => {
7274
expect(result).toEqual(expected)
7375
})
7476
})
77+
78+
describe('determineFreeDbFlag', () => {
79+
describe.each`
80+
isFreeDb
81+
${true}
82+
${false}
83+
`('when isFreeDb=$isFreeDb', ({ isFreeDb }) => {
84+
beforeEach(() => {
85+
jest.spyOn(store, 'getState').mockImplementation(() => ({
86+
connections: {
87+
instances: {
88+
connectedInstance: {
89+
isFreeDb,
90+
},
91+
},
92+
},
93+
} as RootState))
94+
})
95+
96+
it(`returns { isFree: ${isFreeDb} } for an event in the freeDbEvents list`, () => {
97+
const freeDbEvents = [TelemetryEvent.INSIGHTS_PANEL_OPENED, TelemetryEvent.INSIGHTS_PANEL_CLOSED]
98+
const event = TelemetryEvent.INSIGHTS_PANEL_OPENED
99+
100+
const result = getFreeDbFlag(event, freeDbEvents)
101+
102+
expect(result).toEqual({ isFree: isFreeDb })
103+
})
104+
105+
it('returns {} for an event NOT in the freeDbEvents list', () => {
106+
const freeDbEvents = [TelemetryEvent.INSIGHTS_PANEL_OPENED, TelemetryEvent.INSIGHTS_PANEL_CLOSED]
107+
const event = TelemetryEvent.AI_CHAT_BOT_COMMAND_RUN_CLICKED
108+
109+
const result = getFreeDbFlag(event, freeDbEvents)
110+
111+
expect(result).toEqual({})
112+
})
113+
})
114+
115+
it('returns {} if there is no connected instance', () => {
116+
jest.spyOn(store, 'getState').mockImplementation(() =>
117+
({
118+
connections: {
119+
instances: {},
120+
},
121+
} as RootState))
122+
123+
const freeDbEvents = [TelemetryEvent.INSIGHTS_PANEL_OPENED, TelemetryEvent.INSIGHTS_PANEL_CLOSED]
124+
const event = TelemetryEvent.INSIGHTS_PANEL_OPENED
125+
126+
const result = getFreeDbFlag(event, freeDbEvents)
127+
128+
expect(result).toEqual({})
129+
})
130+
})

0 commit comments

Comments
 (0)