Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ describe('createPayloadListenerFDv2', () => {
const listener = createPayloadListener(dataSourceUpdates, logger, basisReceived);
listener(fullTransferPayload);

expect(logger.debug).toBeCalledWith(expect.stringMatching(/initializing/i));
expect(dataSourceUpdates.applyChanges).toBeCalledWith(
expect(logger.debug).toHaveBeenCalledWith(expect.stringMatching(/initializing/i));
expect(dataSourceUpdates.applyChanges).toHaveBeenCalledWith(
true,
{
features: {
Expand All @@ -134,7 +134,7 @@ describe('createPayloadListenerFDv2', () => {
segkey: { key: 'segkey', version: 2 },
},
},
basisReceived,
expect.any(Function),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: New conditional logic in callback lacks test coverage

The tests were changed from verifying that basisReceived is passed directly to applyChanges to using expect.any(Function), but there's no test that verifies the new conditional behavior. The key new logic (if (payload.state !== '') determines whether basisReceived() is called) is not covered by any test. The tests don't verify that basisReceived is actually invoked when state is non-empty, nor that it's skipped when state is empty (for file data initializer scenarios). This means the core fix described in the PR could regress without test detection.

Additional Locations (1)

Fix in Cursor Fix in Web

{ environmentId: 'envId' },
'initial',
);
Expand All @@ -144,7 +144,7 @@ describe('createPayloadListenerFDv2', () => {
const listener = createPayloadListener(dataSourceUpdates, logger, basisReceived);
listener(changesTransferPayload);

expect(logger.debug).toBeCalledWith(expect.stringMatching(/updating/i));
expect(logger.debug).toHaveBeenCalledWith(expect.stringMatching(/updating/i));
expect(dataSourceUpdates.applyChanges).toHaveBeenCalledTimes(1);
expect(dataSourceUpdates.applyChanges).toHaveBeenNthCalledWith(
1,
Expand All @@ -168,7 +168,7 @@ describe('createPayloadListenerFDv2', () => {
},
},
},
basisReceived,
expect.any(Function),
{ environmentId: 'envId' },
'changes',
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,30 @@ export type SynchronizerDataSource =
| StreamingDataSourceConfiguration;

/**
* This data source will allow developers to define their own composite data source
* @experimental
* This data source will allow developers to define their own composite data source.
* This is a free-form option and is not subject to any backwards compatibility guarantees or semantic
* versioning.
*
* The following example is roughly equivilent to using the {@link StandardDataSourceOptions} with the default values.
* @example
* ```typescript
* dataSource: {
* dataSourceOptionsType: 'custom',
* initializers: [
* {
* type: 'polling'
* },
* ],
* synchronizers: [
* {
* type: 'streaming',
* },
* {
* type: 'polling',
* }
* ],
* }
*/
export interface CustomDataSourceOptions {
dataSourceOptionsType: 'custom';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,14 @@ export const createPayloadListener =
dataSourceUpdates.applyChanges(
payload.basis,
converted,
basisReceived,
() => {
if (payload.state !== '') {
// NOTE: this is a hack right now. The only condition that we will consider a valid basis
// is when there is a valid selector. Currently, the only data source that does not have a
// valid selector is the file data initializer, which will have a blank selector.
basisReceived();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the FDv2 fallback also not have a selector? I may just not know how that part works.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding here, the basis can be consumed without a selector, however that would not be considered a successful initialization from this particular initializer. I think this function might not be named correctly here as from the invocation it is simply a success callback (

payloadListener = createPayloadListener(dataSourceUpdates, logger, initSuccess);
). @tanderson-ld thoughts?

}
},
initMetadata,
payload.state,
);
Expand Down