-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement tracking as per spec (#1020)
📣 This was a draft for a while, but is now ready for review! 📣 This implements tracking as per spec, in the server, web, and react SDKs. I don't think the Angular or Nest SDKs need specific implementations, but please advise (cc @luizgribeiro @lukas-reining). Fixes: #1033 Fixes: #1034 --------- Signed-off-by: Todd Baert <[email protected]>
- Loading branch information
Showing
30 changed files
with
445 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './use-track'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import type { Tracking, TrackingEventDetails } from '@openfeature/web-sdk'; | ||
import { useCallback } from 'react'; | ||
import { useOpenFeatureClient } from '../provider'; | ||
|
||
export type Track = { | ||
/** | ||
* Context-aware tracking function for the parent `<OpenFeatureProvider/>`. | ||
* Track a user action or application state, usually representing a business objective or outcome. | ||
* @param trackingEventName an identifier for the event | ||
* @param trackingEventDetails the details of the tracking event | ||
*/ | ||
track: Tracking['track']; | ||
}; | ||
|
||
/** | ||
* Get a context-aware tracking function. | ||
* @returns {Track} context-aware tracking | ||
*/ | ||
export function useTrack(): Track { | ||
const client = useOpenFeatureClient(); | ||
|
||
const track = useCallback((trackingEventName: string, trackingEventDetails?: TrackingEventDetails) => { | ||
client.track(trackingEventName, trackingEventDetails); | ||
}, []); | ||
|
||
return { | ||
track, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { jest } from '@jest/globals'; | ||
import '@testing-library/jest-dom'; // see: https://testing-library.com/docs/react-testing-library/setup | ||
import { render } from '@testing-library/react'; | ||
import * as React from 'react'; | ||
import type { Provider, TrackingEventDetails } from '../src'; | ||
import { | ||
OpenFeature, | ||
OpenFeatureProvider, | ||
useTrack | ||
} from '../src'; | ||
|
||
describe('tracking', () => { | ||
|
||
const eventName = 'test-tracking-event'; | ||
const trackingValue = 1234; | ||
const trackingDetails: TrackingEventDetails = { | ||
value: trackingValue, | ||
}; | ||
const domain = 'someDomain'; | ||
|
||
const mockProvider = () => { | ||
const mockProvider: Provider = { | ||
metadata: { | ||
name: 'mock', | ||
}, | ||
|
||
track: jest.fn((): void => { | ||
return; | ||
}), | ||
} as unknown as Provider; | ||
|
||
return mockProvider; | ||
}; | ||
|
||
describe('no domain', () => { | ||
it('should call default provider', async () => { | ||
|
||
const provider = mockProvider(); | ||
await OpenFeature.setProviderAndWait(provider); | ||
|
||
function Component() { | ||
const { track } = useTrack(); | ||
track(eventName, trackingDetails); | ||
|
||
return <div></div>; | ||
} | ||
|
||
render( | ||
<OpenFeatureProvider suspend={false} > | ||
<Component></Component> | ||
</OpenFeatureProvider>, | ||
); | ||
|
||
expect(provider.track).toHaveBeenCalledWith( | ||
eventName, | ||
expect.anything(), | ||
expect.objectContaining({ value: trackingValue }), | ||
); | ||
}); | ||
}); | ||
|
||
describe('domain set', () => { | ||
it('should call provider for domain', async () => { | ||
|
||
const domainProvider = mockProvider(); | ||
await OpenFeature.setProviderAndWait(domain, domainProvider); | ||
|
||
function Component() { | ||
const { track } = useTrack(); | ||
track(eventName, trackingDetails); | ||
|
||
return <div></div>; | ||
} | ||
|
||
render( | ||
<OpenFeatureProvider domain={domain} suspend={false} > | ||
<Component></Component> | ||
</OpenFeatureProvider>, | ||
); | ||
|
||
expect(domainProvider.track).toHaveBeenCalledWith( | ||
eventName, | ||
expect.anything(), | ||
expect.objectContaining({ value: trackingValue }), | ||
); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './tracking'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { EvaluationContext, TrackingEventDetails } from '@openfeature/core'; | ||
|
||
export interface Tracking { | ||
|
||
/** | ||
* Track a user action or application state, usually representing a business objective or outcome. | ||
* @param trackingEventName an identifier for the event | ||
* @param context the evaluation context | ||
* @param trackingEventDetails the details of the tracking event | ||
*/ | ||
track(trackingEventName: string, context?: EvaluationContext, trackingEventDetails?: TrackingEventDetails): void; | ||
} |
Oops, something went wrong.