Skip to content

Commit

Permalink
Use New Domains (#486)
Browse files Browse the repository at this point in the history
  • Loading branch information
sroyal-statsig authored May 7, 2024
1 parent d6159c2 commit 8c41343
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 83 deletions.
2 changes: 1 addition & 1 deletion src/ErrorBoundary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import StatsigSDKOptions from './StatsigSDKOptions';
import Diagnostics from './utils/Diagnostics';
import OutputLogger from './utils/OutputLogger';
import parseError from './utils/parseError';
export const ExceptionEndpoint = 'https://statsigapi.net/v1/sdk_exception';
export const ExceptionEndpoint = 'https://prodregistryv2.org/v1/rgstr_e';

type ExtraDataExtractor = () => Record<string, unknown>;

Expand Down
2 changes: 1 addition & 1 deletion src/StatsigNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import OutputLogger from './utils/OutputLogger';
export enum StatsigEndpoint {
Initialize = 'initialize',
Rgstr = 'rgstr',
LogEventBeacon = 'log_event_beacon',
LogEventBeacon = 'rgstr_b',
}

type NetworkResponse = Response & {
Expand Down
4 changes: 2 additions & 2 deletions src/StatsigSDKOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import FeatureGate from './FeatureGate';
import Layer from './Layer';
import { StatsigUser } from './StatsigUser';

const DEFAULT_FEATURE_GATE_API = 'https://featuregates.org/v1/';
const DEFAULT_EVENT_LOGGING_API = 'https://events.statsigapi.net/v1/';
const DEFAULT_FEATURE_GATE_API = 'https://featureassets.org/v1/';
const DEFAULT_EVENT_LOGGING_API = 'https://prodregistryv2.org/v1/';
const DEFAULT_INIT_NETWORK_RETRIES = 3;

export const INIT_TIMEOUT_DEFAULT_MS = 3000;
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/Bootstrapping.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('Statsig Client Bootstrapping', () => {
url &&
typeof url === 'string' &&
url.includes('initialize') &&
url !== 'https://featuregates.org/v1/initialize'
url !== 'https://featureassets.org/v1/initialize'
) {
return Promise.reject(new Error('invalid initialize endpoint'));
}
Expand Down
23 changes: 12 additions & 11 deletions src/__tests__/InitTimeout.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('Init Timeout', () => {
has_updates: true,
time: 123456789,
};

let respObject: any = baseInitResponse;
const localStorage = new LocalStorageMock();
// @ts-ignore
Expand All @@ -44,12 +44,10 @@ describe('Init Timeout', () => {

// @ts-ignore
global.fetch = jest.fn((url, params) => {
if (
url.toString() !== 'https://featuregates.org/v1/initialize'
) {
if (url.toString() !== 'https://featureassets.org/v1/initialize') {
return Promise.reject(new Error('invalid initialize endpoint'));
}

return Promise.resolve({
ok: true,
text: () => Promise.resolve(JSON.stringify(respObject)),
Expand All @@ -63,12 +61,15 @@ describe('Init Timeout', () => {
window.localStorage.clear();
});


test('that override APIs work', async () => {
const spy = jest.spyOn(global, 'clearTimeout');
const statsig = new StatsigClient(sdkKey, { userID: '123' }, {
initTimeoutMs: 9999
});
const statsig = new StatsigClient(
sdkKey,
{ userID: '123' },
{
initTimeoutMs: 9999,
},
);
await statsig.initializeAsync();

expect(statsig.checkGate('test_gate')).toBe(true);
Expand Down Expand Up @@ -103,7 +104,7 @@ describe('Init Timeout', () => {

afterAll(() => {
jest.resetModules();
})
});

it('does not throw with updateUser timeout, applies timeout', async () => {
const start = Date.now();
Expand All @@ -119,4 +120,4 @@ describe('Init Timeout', () => {
expect(end - start).toBeGreaterThanOrEqual(NETWORK_TIME);
});
});
});
});
141 changes: 81 additions & 60 deletions src/__tests__/Logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('Verify behavior of StatsigLogger', () => {
//@ts-ignore
global.fetch = jest.fn((url) => {
if (url && typeof url === 'string' && url.includes('rgstr')) {
if (url !== 'https://events.statsigapi.net/v1/rgstr') {
if (url !== 'https://prodregistryv2.org/v1/rgstr') {
fail('invalid logevent endpoint');
}
return Promise.resolve({
Expand Down Expand Up @@ -79,33 +79,32 @@ describe('Verify behavior of StatsigLogger', () => {
});

describe('Log Events Failure', () => {
let client: StatsigClient
let networkSpy: jest.SpyInstance<unknown>
let spyOnEB:jest.SpyInstance<unknown>
let spyOnLog: jest.SpyInstance<unknown>
let spyOnFlush: jest.SpyInstance<unknown>
let spyOnResend: jest.SpyInstance<unknown>
let logger: StatsigLogger
let client: StatsigClient;
let networkSpy: jest.SpyInstance<unknown>;
let spyOnEB: jest.SpyInstance<unknown>;
let spyOnLog: jest.SpyInstance<unknown>;
let spyOnFlush: jest.SpyInstance<unknown>;
let spyOnResend: jest.SpyInstance<unknown>;
let logger: StatsigLogger;
beforeEach(async () => {
client = new StatsigClient(
sdkKey,
{ userID: 'user_key' },
{ disableDiagnosticsLogging: true },
);
StatsigClient.setAsyncStorage(fakeAsyncStorage)
networkSpy = jest.spyOn(client.getNetwork(), 'postToEndpoint')
StatsigClient.setAsyncStorage(fakeAsyncStorage);
networkSpy = jest.spyOn(client.getNetwork(), 'postToEndpoint');
// Mock postToEndpoint directly so we bypass retry to speed up tests
networkSpy.mockImplementation((endpointName) => {
if(endpointName == 'initialize') {
if (endpointName == 'initialize') {
const response = {
ok: true,
status: 200,
headers: requestHeaders,
} as Response
return Promise.resolve(
{
...response,
data:{
} as Response;
return Promise.resolve({
...response,
data: {
gates: {},
feature_gates: {
'AoZS0F06Ub+W2ONx+94rPTS7MRxuxa+GnXro5Q1uaGY=': {
Expand All @@ -120,24 +119,23 @@ describe('Verify behavior of StatsigLogger', () => {
},
},
configs: {},
}},
)
},
});
}
return Promise.reject("Sample error")
})
logger = client.getLogger()
return Promise.reject('Sample error');
});
logger = client.getLogger();
spyOnFlush = jest.spyOn(logger, 'flush');
spyOnLog = jest.spyOn(logger, 'log');
spyOnResend = jest.spyOn(client.getLogger(), "sendSavedRequests")
spyOnEB = jest.spyOn(client.getErrorBoundary(), "logError")
})
spyOnResend = jest.spyOn(client.getLogger(), 'sendSavedRequests');
spyOnEB = jest.spyOn(client.getErrorBoundary(), 'logError');
});

afterEach(() => {
networkSpy.mockClear()
})
networkSpy.mockClear();
});

it('Save to cache when failure', async () => {

// @ts-ignore access private attribute
expect(client.getLogger().flushInterval).not.toBeNull();

Expand All @@ -159,49 +157,72 @@ describe('Verify behavior of StatsigLogger', () => {
}
expect(spyOnFlush).toHaveBeenCalledTimes(1);
expect(spyOnLog).toHaveBeenCalledTimes(102);
client.shutdown()
await waitAllPromises()
const savedLoggingRequest = await fakeAsyncStorage.getItem('STATSIG_LOCAL_STORAGE_LOGGING_REQUEST')
expect(JSON.parse(savedLoggingRequest ?? "")).toMatchObject([{ "events": expect.any(Array), "statsigMetadata": expect.any(Object), "time": expect.any(Number) }, { "events": expect.any(Array), "statsigMetadata": expect.any(Object), "time": expect.any(Number) }])
client.shutdown();
await waitAllPromises();
const savedLoggingRequest = await fakeAsyncStorage.getItem(
'STATSIG_LOCAL_STORAGE_LOGGING_REQUEST',
);
expect(JSON.parse(savedLoggingRequest ?? '')).toMatchObject([
{
events: expect.any(Array),
statsigMetadata: expect.any(Object),
time: expect.any(Number),
},
{
events: expect.any(Array),
statsigMetadata: expect.any(Object),
time: expect.any(Number),
},
]);
});
});

it("Retry on restart", async () => {
it('Retry on restart', async () => {
// No events have been dropped yet
await client.initializeAsync()
expect(spyOnEB).not.toBeCalled()
expect(spyOnResend).toBeCalledTimes(1)
client.shutdown()
})
await client.initializeAsync();
expect(spyOnEB).not.toBeCalled();
expect(spyOnResend).toBeCalledTimes(1);
client.shutdown();
});

it("Drop events when too old when retry at initialization", async () => {
it('Drop events when too old when retry at initialization', async () => {
const eightDaysLater = Date.now() + 8 * 24 * 60 * 60 * 1000;
jest.spyOn(global.Date, 'now').mockImplementation(() => eightDaysLater);
await client.initializeAsync()
expect(spyOnResend).toBeCalledTimes(1)
await client.initializeAsync();
expect(spyOnResend).toBeCalledTimes(1);
// Drop 3 batches, 2 from frist session within test and 1 from second session
await waitAllPromises()
expect(spyOnEB).toBeCalledTimes(3)
client.shutdown()
await waitAllPromises()
const savedLoggingRequest = await fakeAsyncStorage.getItem('STATSIG_LOCAL_STORAGE_LOGGING_REQUEST') ?? ""
const parsedSavedLoggingRequest = JSON.parse(savedLoggingRequest) as FailedLogEventBody[]
expect(parsedSavedLoggingRequest.length).toBe(1)
})
await waitAllPromises();
expect(spyOnEB).toBeCalledTimes(3);
client.shutdown();
await waitAllPromises();
const savedLoggingRequest =
(await fakeAsyncStorage.getItem(
'STATSIG_LOCAL_STORAGE_LOGGING_REQUEST',
)) ?? '';
const parsedSavedLoggingRequest = JSON.parse(
savedLoggingRequest,
) as FailedLogEventBody[];
expect(parsedSavedLoggingRequest.length).toBe(1);
});

it("Stop adding events(dropping) if too much", async () => {
fakeAsyncStorage.removeItem('STATSIG_LOCAL_STORAGE_LOGGING_REQUEST')
it('Stop adding events(dropping) if too much', async () => {
fakeAsyncStorage.removeItem('STATSIG_LOCAL_STORAGE_LOGGING_REQUEST');
for (let i = 0; i < 1005; i++) {
client.logEvent("test_event");
client.logEvent('test_event');
}
client.shutdown()
await waitAllPromises()
// Dropping last batch because it's too much
expect(spyOnEB).toBeCalledTimes(1)
const savedLoggingRequest = await fakeAsyncStorage.getItem('STATSIG_LOCAL_STORAGE_LOGGING_REQUEST') ?? ""
const parsedSavedLoggingRequest = JSON.parse(savedLoggingRequest) as FailedLogEventBody[]
expect(parsedSavedLoggingRequest.length).toBe(10)
})
client.shutdown();
await waitAllPromises();
// Dropping last batch because it's too much
expect(spyOnEB).toBeCalledTimes(1);
const savedLoggingRequest =
(await fakeAsyncStorage.getItem(
'STATSIG_LOCAL_STORAGE_LOGGING_REQUEST',
)) ?? '';
const parsedSavedLoggingRequest = JSON.parse(
savedLoggingRequest,
) as FailedLogEventBody[];
expect(parsedSavedLoggingRequest.length).toBe(10);
});
});

test('local mode does not set up a flush interval', () => {
Expand Down Expand Up @@ -315,7 +336,7 @@ describe('Verify behavior of StatsigLogger', () => {
event.setMetadata({
context: 'initialize',
statsigOptions: {
"disableCurrentPageLogging": true,
disableCurrentPageLogging: true,
},
markers: [
{
Expand Down
10 changes: 5 additions & 5 deletions src/__tests__/StatsigClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ describe('Verify behavior of StatsigClient', () => {
global.fetch = jest.fn((url, params) => {
if (
![
'https://featuregates.org/v1/initialize',
'https://featuregates.org/v1/initialize_with_deltas',
'https://featureassets.org/v1/initialize',
'https://featureassets.org/v1/initialize_with_deltas',
].includes(url.toString())
) {
return Promise.reject(new Error('invalid initialize endpoint'));
Expand Down Expand Up @@ -200,12 +200,12 @@ describe('Verify behavior of StatsigClient', () => {
await statsig.initializeAsync();

expect(statsig.getOptions().getApi()).toEqual(
'https://featuregates.org/v1/',
'https://featureassets.org/v1/',
);
expect(statsig.getOptions().getLoggingBufferMaxSize()).toEqual(500);
expect(statsig.getOptions().getLoggingIntervalMillis()).toEqual(1000);
expect(statsig.getOptions().getEventLoggingApi()).toEqual(
'https://events.statsigapi.net/v1/',
'https://prodregistryv2.org/v1/',
);

// Set the stable id, save the configs
Expand Down Expand Up @@ -255,7 +255,7 @@ describe('Verify behavior of StatsigClient', () => {
await statsig.initializeAsync();

expect(statsig.getOptions().getApi()).toEqual(
'https://featuregates.org/v1/',
'https://featureassets.org/v1/',
);
expect(statsig.getOptions().getEventLoggingApi()).toEqual(
'https://logging.jkw.com/v1/',
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/StatsigNoContent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('Verify behavior of StatsigClient when 204 returned from initialize', (
url &&
typeof url === 'string' &&
url.includes('initialize') &&
url !== 'https://featuregates.org/v1/initialize'
url !== 'https://featureassets.org/v1/initialize'
) {
return Promise.reject(new Error('invalid initialize endpoint'));
}
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/StatsigSinceTime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('Verify behavior of StatsigClient with sinceTime', () => {
url &&
typeof url === 'string' &&
url.includes('initialize') &&
url !== 'https://featuregates.org/v1/initialize'
url !== 'https://featureassets.org/v1/initialize'
) {
return Promise.reject(new Error('invalid initialize endpoint'));
}
Expand Down

0 comments on commit 8c41343

Please sign in to comment.