Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/browser/src/integration/amplitude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type AmplitudeInstance = {
options?: AmplitudeOptions;
_ua?: AmplitudeUAParser;
logEvent(eventName: string, properties: Record<string, string>): void;
setUserProperties(userProperties: Record<string, unknown>): void;
};

type AmplitudeOptions = {
Expand Down Expand Up @@ -77,6 +78,9 @@ export class AmplitudeAnalyticsProvider implements ExperimentAnalyticsProvider {
}

track(event: ExperimentAnalyticsEvent): void {
if (event.userProperties) {
this.amplitudeInstance.setUserProperties(event.userProperties);
}
this.amplitudeInstance.logEvent(event.name, event.properties);
}
}
9 changes: 8 additions & 1 deletion packages/browser/src/types/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@ export interface ExperimentAnalyticsEvent {
name: string;

/**
* Properties for the analytics event. Should be passed as the event
* Event properties for the analytics event. Should be passed as the event
* properties to the analytics implementation provided by the
* {@link ExperimentAnalyticsProvider}.
*/
properties: Record<string, string>;

/**
* Custom user properties
*/
userProperties?: Record<string, unknown>;
}

/**
Expand All @@ -30,6 +35,7 @@ export interface ExperimentAnalyticsEvent {
export class ExposureEvent implements ExperimentAnalyticsEvent {
name = '[Experiment] Exposure';
properties: Record<string, string>;
userProperties?: Record<string, unknown>;

/**
* The user exposed to the flag/experiment variant.
Expand All @@ -53,5 +59,6 @@ export class ExposureEvent implements ExperimentAnalyticsEvent {
key: key,
variant: variant.value,
};
this.userProperties = user.user_properties;
}
}
25 changes: 23 additions & 2 deletions packages/browser/test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ test('ExperimentClient.fetch, with config user provider, success', async () => {
*/
class TestAnalyticsProvider implements ExperimentAnalyticsProvider {
public didTrack = false;
public block: (ExposureEvent) => void;
public constructor(block: (ExposureEvent) => void) {
public block: (event: ExperimentAnalyticsEvent) => void;
public constructor(block: (event: ExperimentAnalyticsEvent) => void) {
this.block = block;
}
track(event: ExperimentAnalyticsEvent): void {
Expand Down Expand Up @@ -273,3 +273,24 @@ test('ExperimentClient.variant, with analytics provider, exposure not tracked on
client.variant(initialKey);
client.variant(unknownKey);
});

/**
* Configure a client with an analytics provider which checks that
* user_properties from the ExperimentUser object are passed through the event
* to the analytics provider.
*/
test('ExperimentClient.variant, with analytics provider, user properties tracked', async () => {
const userProperties = { string: 'string', bool: true, number: 13121 };
const analyticsProvider = new TestAnalyticsProvider(
(event: ExperimentAnalyticsEvent) => {
expect(event.userProperties).toEqual(userProperties);
},
);
const client = new ExperimentClient(API_KEY, {
debug: true,
analyticsProvider: analyticsProvider,
});
await client.fetch({ user_properties: userProperties, ...testUser });
client.variant(serverKey);
expect(analyticsProvider.didTrack).toEqual(true);
});