2021-07-23 15:47:02 +00:00
|
|
|
import { Anonymity, getRedactedCurrentLocation, IAnonymousEvent, IPseudonymousEvent, IRoomEvent,
|
2021-07-21 12:48:10 +00:00
|
|
|
PosthogAnalytics } from '../src/PosthogAnalytics';
|
2021-07-21 06:40:39 +00:00
|
|
|
import SdkConfig from '../src/SdkConfig';
|
2021-07-28 10:22:40 +00:00
|
|
|
import crypto = require('crypto');
|
2021-07-21 06:40:39 +00:00
|
|
|
|
|
|
|
class FakePosthog {
|
|
|
|
public capture;
|
|
|
|
public init;
|
2021-07-21 07:38:58 +00:00
|
|
|
public identify;
|
2021-07-28 08:37:08 +00:00
|
|
|
public reset;
|
|
|
|
public register;
|
2021-07-21 06:40:39 +00:00
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.capture = jest.fn();
|
|
|
|
this.init = jest.fn();
|
2021-07-21 07:38:58 +00:00
|
|
|
this.identify = jest.fn();
|
2021-07-28 08:37:08 +00:00
|
|
|
this.reset = jest.fn();
|
|
|
|
this.register = jest.fn();
|
2021-07-21 06:40:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-21 07:23:42 +00:00
|
|
|
export interface ITestEvent extends IAnonymousEvent {
|
2021-07-21 06:40:39 +00:00
|
|
|
key: "jest_test_event",
|
|
|
|
properties: {
|
|
|
|
foo: string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-23 15:47:02 +00:00
|
|
|
export interface ITestPseudonymousEvent extends IPseudonymousEvent {
|
|
|
|
key: "jest_test_pseudo_event",
|
|
|
|
properties: {
|
|
|
|
foo: string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-21 07:23:42 +00:00
|
|
|
export interface ITestRoomEvent extends IRoomEvent {
|
|
|
|
key: "jest_test_room_event",
|
|
|
|
properties: {
|
|
|
|
foo: string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-21 06:40:39 +00:00
|
|
|
describe("PosthogAnalytics", () => {
|
|
|
|
let fakePosthog: FakePosthog;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
fakePosthog = new FakePosthog();
|
2021-07-28 08:37:08 +00:00
|
|
|
|
2021-07-21 06:40:39 +00:00
|
|
|
window.crypto = {
|
|
|
|
subtle: crypto.webcrypto.subtle,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
window.crypto = null;
|
|
|
|
});
|
|
|
|
|
2021-07-21 13:57:24 +00:00
|
|
|
describe("Initialisation", () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
it("Should not be enabled without config being set", () => {
|
2021-07-21 13:57:24 +00:00
|
|
|
jest.spyOn(SdkConfig, "get").mockReturnValue({});
|
2021-07-28 08:37:08 +00:00
|
|
|
const analytics = new PosthogAnalytics(fakePosthog);
|
2021-07-21 13:57:24 +00:00
|
|
|
expect(analytics.isEnabled()).toBe(false);
|
|
|
|
});
|
2021-07-21 06:40:39 +00:00
|
|
|
|
2021-07-28 08:37:08 +00:00
|
|
|
it("Should be enabled if config is set", () => {
|
2021-07-21 13:57:24 +00:00
|
|
|
jest.spyOn(SdkConfig, "get").mockReturnValue({
|
|
|
|
posthog: {
|
|
|
|
projectApiKey: "foo",
|
|
|
|
apiHost: "bar",
|
|
|
|
},
|
|
|
|
});
|
2021-07-28 08:37:08 +00:00
|
|
|
const analytics = new PosthogAnalytics(fakePosthog);
|
|
|
|
analytics.setAnonymity(Anonymity.Pseudonymous);
|
2021-07-21 13:57:24 +00:00
|
|
|
expect(analytics.isEnabled()).toBe(true);
|
2021-07-21 06:40:39 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-07-21 13:57:24 +00:00
|
|
|
describe("Tracking", () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
let analytics: PosthogAnalytics;
|
|
|
|
|
2021-07-21 13:57:24 +00:00
|
|
|
beforeEach(() => {
|
|
|
|
jest.spyOn(SdkConfig, "get").mockReturnValue({
|
|
|
|
posthog: {
|
|
|
|
projectApiKey: "foo",
|
|
|
|
apiHost: "bar",
|
|
|
|
},
|
|
|
|
});
|
2021-07-28 08:37:08 +00:00
|
|
|
|
|
|
|
analytics = new PosthogAnalytics(fakePosthog);
|
2021-07-21 06:40:39 +00:00
|
|
|
});
|
2021-07-21 06:42:55 +00:00
|
|
|
|
2021-07-23 15:47:02 +00:00
|
|
|
it("Should pass trackAnonymousEvent() to posthog", async () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
analytics.setAnonymity(Anonymity.Pseudonymous);
|
2021-07-21 13:57:24 +00:00
|
|
|
await analytics.trackAnonymousEvent<ITestEvent>("jest_test_event", {
|
|
|
|
foo: "bar",
|
|
|
|
});
|
|
|
|
expect(fakePosthog.capture.mock.calls[0][0]).toBe("jest_test_event");
|
2021-07-21 15:06:09 +00:00
|
|
|
expect(fakePosthog.capture.mock.calls[0][1]["foo"]).toEqual("bar");
|
2021-07-21 06:42:55 +00:00
|
|
|
});
|
2021-07-21 07:23:42 +00:00
|
|
|
|
2021-07-21 13:57:24 +00:00
|
|
|
it("Should pass trackRoomEvent to posthog", async () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
analytics.setAnonymity(Anonymity.Pseudonymous);
|
2021-07-21 13:57:24 +00:00
|
|
|
const roomId = "42";
|
|
|
|
await analytics.trackRoomEvent<IRoomEvent>("jest_test_event", roomId, {
|
|
|
|
foo: "bar",
|
|
|
|
});
|
|
|
|
expect(fakePosthog.capture.mock.calls[0][0]).toBe("jest_test_event");
|
2021-07-21 15:06:09 +00:00
|
|
|
expect(fakePosthog.capture.mock.calls[0][1]["foo"]).toEqual("bar");
|
|
|
|
expect(fakePosthog.capture.mock.calls[0][1]["hashedRoomId"])
|
|
|
|
.toEqual("73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049");
|
2021-07-21 07:23:42 +00:00
|
|
|
});
|
2021-07-21 07:38:58 +00:00
|
|
|
|
2021-07-23 15:47:02 +00:00
|
|
|
it("Should pass trackPseudonymousEvent() to posthog", async () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
analytics.setAnonymity(Anonymity.Pseudonymous);
|
2021-07-23 15:47:02 +00:00
|
|
|
await analytics.trackPseudonymousEvent<ITestEvent>("jest_test_pseudo_event", {
|
2021-07-21 13:57:24 +00:00
|
|
|
foo: "bar",
|
|
|
|
});
|
2021-07-23 15:47:02 +00:00
|
|
|
expect(fakePosthog.capture.mock.calls[0][0]).toBe("jest_test_pseudo_event");
|
|
|
|
expect(fakePosthog.capture.mock.calls[0][1]["foo"]).toEqual("bar");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Should not track pseudonymous messages if anonymous", async () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
analytics.setAnonymity(Anonymity.Anonymous);
|
2021-07-21 13:57:24 +00:00
|
|
|
await analytics.trackPseudonymousEvent<ITestEvent>("jest_test_event", {
|
|
|
|
foo: "bar",
|
|
|
|
});
|
|
|
|
expect(fakePosthog.capture.mock.calls.length).toBe(0);
|
|
|
|
});
|
2021-07-21 12:48:10 +00:00
|
|
|
|
2021-07-23 15:47:02 +00:00
|
|
|
it("Should not track any events if disabled", async () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
analytics.setAnonymity(Anonymity.Disabled);
|
2021-07-23 15:47:02 +00:00
|
|
|
await analytics.trackPseudonymousEvent<ITestEvent>("jest_test_event", {
|
|
|
|
foo: "bar",
|
|
|
|
});
|
|
|
|
await analytics.trackAnonymousEvent<ITestEvent>("jest_test_event", {
|
|
|
|
foo: "bar",
|
|
|
|
});
|
|
|
|
await analytics.trackRoomEvent<ITestRoomEvent>("room id", "jest_test_room_event", {
|
|
|
|
foo: "bar",
|
|
|
|
});
|
|
|
|
await analytics.trackPageView(200);
|
|
|
|
expect(fakePosthog.capture.mock.calls.length).toBe(0);
|
|
|
|
});
|
|
|
|
|
2021-07-21 13:57:24 +00:00
|
|
|
it("Should pseudonymise a location of a known screen", async () => {
|
|
|
|
const location = await getRedactedCurrentLocation(
|
|
|
|
"https://foo.bar", "#/register/some/pii", "/", Anonymity.Pseudonymous);
|
|
|
|
expect(location).toBe(
|
|
|
|
`https://foo.bar/#/register/\
|
2021-07-21 12:48:10 +00:00
|
|
|
a6b46dd0d1ae5e86cbc8f37e75ceeb6760230c1ca4ffbcb0c97b96dd7d9c464b/\
|
|
|
|
bd75b3e080945674c0351f75e0db33d1e90986fa07b318ea7edf776f5eef38d4`);
|
2021-07-21 13:57:24 +00:00
|
|
|
});
|
2021-07-21 12:48:10 +00:00
|
|
|
|
2021-07-21 13:57:24 +00:00
|
|
|
it("Should anonymise a location of a known screen", async () => {
|
|
|
|
const location = await getRedactedCurrentLocation(
|
|
|
|
"https://foo.bar", "#/register/some/pii", "/", Anonymity.Anonymous);
|
|
|
|
expect(location).toBe("https://foo.bar/#/register/<redacted>/<redacted>");
|
|
|
|
});
|
2021-07-21 12:48:10 +00:00
|
|
|
|
2021-07-21 13:57:24 +00:00
|
|
|
it("Should pseudonymise a location of an unknown screen", async () => {
|
|
|
|
const location = await getRedactedCurrentLocation(
|
|
|
|
"https://foo.bar", "#/not_a_screen_name/some/pii", "/", Anonymity.Pseudonymous);
|
|
|
|
expect(location).toBe(
|
|
|
|
`https://foo.bar/#/<redacted_screen_name>/\
|
2021-07-21 12:48:10 +00:00
|
|
|
a6b46dd0d1ae5e86cbc8f37e75ceeb6760230c1ca4ffbcb0c97b96dd7d9c464b/\
|
|
|
|
bd75b3e080945674c0351f75e0db33d1e90986fa07b318ea7edf776f5eef38d4`);
|
2021-07-21 13:57:24 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it("Should anonymise a location of an unknown screen", async () => {
|
|
|
|
const location = await getRedactedCurrentLocation(
|
|
|
|
"https://foo.bar", "#/not_a_screen_name/some/pii", "/", Anonymity.Anonymous);
|
|
|
|
expect(location).toBe("https://foo.bar/#/<redacted_screen_name>/<redacted>/<redacted>");
|
|
|
|
});
|
2021-07-21 12:48:10 +00:00
|
|
|
|
2021-07-28 08:54:37 +00:00
|
|
|
it("Should handle an empty hash", async () => {
|
2021-07-27 12:29:56 +00:00
|
|
|
const location = await getRedactedCurrentLocation(
|
|
|
|
"https://foo.bar", "", "/", Anonymity.Anonymous);
|
|
|
|
expect(location).toBe("https://foo.bar/");
|
|
|
|
});
|
|
|
|
|
2021-07-21 13:57:24 +00:00
|
|
|
it("Should identify the user to posthog if pseudonymous", async () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
analytics.setAnonymity(Anonymity.Pseudonymous);
|
2021-07-21 13:57:24 +00:00
|
|
|
await analytics.identifyUser("foo");
|
|
|
|
expect(fakePosthog.identify.mock.calls[0][0])
|
|
|
|
.toBe("2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Should not identify the user to posthog if anonymous", async () => {
|
2021-07-28 08:37:08 +00:00
|
|
|
analytics.setAnonymity(Anonymity.Anonymous);
|
2021-07-21 13:57:24 +00:00
|
|
|
await analytics.identifyUser("foo");
|
|
|
|
expect(fakePosthog.identify.mock.calls.length).toBe(0);
|
|
|
|
});
|
2021-07-21 07:38:58 +00:00
|
|
|
});
|
2021-07-21 06:40:39 +00:00
|
|
|
});
|