Add analytics tracking for URL previews (#32659)

* Add analytics tracking.

* fix import

* fix other import too

* fixup type

* Add test case

* Add better testing

* make it happier

* update lock
This commit is contained in:
Will Hunt
2026-03-30 10:10:46 +00:00
committed by GitHub
parent f28fca76eb
commit e0cf78b5b8
7 changed files with 151 additions and 4 deletions
@@ -1,4 +1,5 @@
/*
Copyright 2026 Element Creations Ltd.
Copyright 2024 New Vector Ltd.
Copyright 2021 The Matrix.org Foundation C.I.C.
@@ -205,6 +206,10 @@ describe("PosthogAnalytics", () => {
analytics.setAnonymity(Anonymity.Pseudonymous);
});
afterEach(() => {
SettingsStore.reset();
});
it("should send layout IRC correctly", async () => {
await SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
defaultDispatcher.dispatch(
@@ -217,7 +222,7 @@ describe("PosthogAnalytics", () => {
analytics.trackEvent<ITestEvent>({
eventName: "JestTestEvents",
});
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toStrictEqual({
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toMatchObject({
WebLayout: "IRC",
});
});
@@ -234,7 +239,7 @@ describe("PosthogAnalytics", () => {
analytics.trackEvent<ITestEvent>({
eventName: "JestTestEvents",
});
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toStrictEqual({
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toMatchObject({
WebLayout: "Bubble",
});
});
@@ -251,7 +256,7 @@ describe("PosthogAnalytics", () => {
analytics.trackEvent<ITestEvent>({
eventName: "JestTestEvents",
});
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toStrictEqual({
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toMatchObject({
WebLayout: "Group",
});
});
@@ -269,12 +274,51 @@ describe("PosthogAnalytics", () => {
analytics.trackEvent<ITestEvent>({
eventName: "JestTestEvents",
});
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toStrictEqual({
console.log(mocked(fakePosthog).capture.mock.calls[0]);
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toMatchObject({
WebLayout: "Compact",
});
});
});
describe("UrlPreviews", () => {
let analytics: PosthogAnalytics;
beforeEach(() => {
SdkConfig.put({
brand: "Testing",
posthog: {
project_api_key: "foo",
api_host: "bar",
},
});
analytics = new PosthogAnalytics(fakePosthog);
analytics.setAnonymity(Anonymity.Pseudonymous);
});
afterEach(() => {
SdkConfig.reset();
});
it("should set UrlPreviewsEnabled on change", async () => {
defaultDispatcher.dispatch(
{
action: Action.SettingUpdated,
settingName: "urlPreviewsEnabled",
newValue: true,
},
true,
);
analytics.trackEvent<ITestEvent>({
eventName: "JestTestEvents",
});
expect(mocked(fakePosthog).capture.mock.calls[0][1]!["$set"]).toMatchObject({
URLPreviewsEnabled: true,
});
});
});
describe("CryptoSdk", () => {
let analytics: PosthogAnalytics;
const getFakeClient = (): MatrixClient =>
@@ -0,0 +1,45 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { PosthogAnalytics } from "../../src/PosthogAnalytics";
import PosthogTrackers from "../../src/PosthogTrackers";
describe("PosthogTrackers", () => {
afterEach(() => {
jest.resetAllMocks();
});
it("tracks URL Previews", () => {
jest.spyOn(PosthogAnalytics.instance, "trackEvent");
const tracker = new PosthogTrackers();
tracker.trackUrlPreview("$123456", false, [
{
title: "A preview",
image: {
imageThumb: "abc",
imageFull: "abc",
},
link: "a-link",
},
]);
tracker.trackUrlPreview("$123456", false, [
{
title: "A second preview",
link: "a-link",
},
]);
// Ignores subsequent calls.
expect(PosthogAnalytics.instance.trackEvent).toHaveBeenCalledWith({
eventName: "UrlPreviewRendered",
previewKind: "LegacyCard",
hasThumbnail: true,
previewCount: 1,
encryptedRoom: false,
});
expect(PosthogAnalytics.instance.trackEvent).toHaveBeenCalledTimes(1);
});
});