Skip to content

Commit

Permalink
Merge pull request #38 from gotokatsuya/patch/userid-string-type
Browse files Browse the repository at this point in the history
#37 feat: support string userId
  • Loading branch information
ZigZagT committed Jul 15, 2021
2 parents 72063cc + 66fbdad commit 026ebcc
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 13 deletions.
43 changes: 38 additions & 5 deletions packages/ab-testing/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ describe('ab-testing module', () => {
},
],
},
{
name: 'experiment_3',
cohorts: [
{ name: 'control', force_include: {} },
{
name: 'test_allocation',
allocation: [[0, 50]],
},
{
name: 'test_force_include',
force_include: hashObject(
{
user_id: ['123456789'],
},
salt
),
},
],
},
],
salt,
};
Expand Down Expand Up @@ -183,6 +202,20 @@ describe('ab-testing module', () => {
hashObject({ user_id: 1, email_domain: 'a.com' }, config.salt)
).getCohort('experiment_2')
).toEqual('test_force_include');
expect(
new Experiments(
config,
'12345',
hashObject({ user_id: '12345' }, config.salt)
).getCohort('experiment_3')
).toEqual('control');
expect(
new Experiments(
config,
'123456789',
hashObject({ user_id: '123456789' }, config.salt)
).getCohort('experiment_3')
).toEqual('test_force_include');
expect(
Array(20)
.fill(0)
Expand All @@ -201,7 +234,7 @@ describe('ab-testing module', () => {
config,
1,
hashObject({ user_id: 1, email_domain: 'example.com' }, config.salt)
).getCohort('experiment_3')
).getCohort('experiment_any')
).toEqual('control');
});

Expand All @@ -215,15 +248,15 @@ describe('ab-testing module', () => {
expect(experiment.getCohort('experiment_2')).toEqual('test_force_include');
});

it('does not show an error message if NODE_ENV is test', () => {
it('does not show an error message if NODE_ENV is test', () => {
const spy = jest.spyOn(console, 'error').mockImplementation();

expect(
new Experiments(
config,
1,
hashObject({ user_id: 1, email_domain: 'example.com' }, config.salt)
).getCohort('experiment_3')
).getCohort('experiment_any')
).toEqual('control');
expect(spy).not.toHaveBeenCalled();
});
Expand All @@ -238,8 +271,8 @@ describe('ab-testing module', () => {
hashObject({ user_id: 1, email_domain: 'example.com' }, config.salt)
);

expect(experiments.getCohort('experiment_3')).toEqual('control');
expect(experiments.hasExperiment('experiment_3')).toBe(false);
expect(experiments.getCohort('experiment_any')).toEqual('control');
expect(experiments.hasExperiment('experiment_any')).toBe(false);
expect(spy).toHaveBeenCalled();

global.process.env.NODE_ENV = initialEnv;
Expand Down
4 changes: 2 additions & 2 deletions packages/ab-testing/src/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ export type ABTestingConfig = {
};
declare export class Experiments {
config: ABTestingConfig;
userId: number;
userId: number | string;
userProfile: {
[s: string]: string,
};
constructor(
config: ABTestingConfig,
userId: number,
userId: number | string,
userProfile: {
[s: string]: string,
}
Expand Down
12 changes: 8 additions & 4 deletions packages/ab-testing/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ export type ABTestingConfig = {
experiments: Experiment[];
};

function getModuloValue(experiment: string, userId: number): number {
function getModuloValue(experiment: string, userId: number | string): number {
return crc32.calculate(String(userId), crc32.calculate(experiment)) % 100;
}

function matchUserCohort(
experimentConfig: Experiment,
userId: number,
userId: number | string,
userProfile: { [s: string]: string }
): string {
const userSegmentNum = getModuloValue(experimentConfig.name, userId);
Expand All @@ -53,11 +53,15 @@ function matchUserCohort(

export class Experiments {
config: { [experimentName: string]: Experiment };
userId: number;
userId: number | string;
userProfile: { [s: string]: string };
matchedCohorts: { [experimentName: string]: string };

constructor(config: ABTestingConfig, userId: number, userProfile: { [s: string]: string }) {
constructor(
config: ABTestingConfig,
userId: number | string,
userProfile: { [s: string]: string }
) {
this.config = {};
this.userId = userId;
this.userProfile = userProfile;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-ab-testing/src/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export type { ABTestingConfig } from '@appannie/ab-testing';

declare export var ABTestingController: React.ComponentType<{
config: ABTestingConfig,
userId: number,
userId: number | string,
userProfile: {
[key: string]: string,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/react-ab-testing/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const ABTestingContext = React.createContext<ABTestingContextType>({

export const ABTestingController: React.FunctionComponent<{
config: ABTestingConfig;
userId: number;
userId: number | string;
userProfile: { [key: string]: string };
children: ReactNode;
}> = ({ config, userId, userProfile, children }) => {
Expand Down

0 comments on commit 026ebcc

Please sign in to comment.