Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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 @@ -197,17 +197,30 @@ const inferSelectOneByTypeReturnStatus = (
};

const inferSelectAllByTypeReturnStatus = (
_guide: KnockGuide,
_snapshot: StoreStateSnapshot,
_stage: KnockGuideClientGroupStage,
_query: SelectionResultByQuery,
guide: KnockGuide,
snapshot: StoreStateSnapshot,
stage: KnockGuideClientGroupStage,
query: SelectionResultByQuery,
): SelectableStatusPresent["status"] => {
// If queried with useGuides/selectGuides (i.e. can return multiple guides),
// then we need to look up the actual query results to figure out how this
// guide may or may not be included in the result.
const result = query.type!.all!;
if (result.size === 0) {
return "queried";
}

// TODO: Placeholder to follow up.
return "returned";
const guides = [...result.values()];
const first = guides[0]!;

// If the first selected guide is unthrottled or resolved, then we should
// have at minimum one guide to return, and potentially more based on whether
// we are throttling currently and which other guides are unthrottled.
if (first.bypass_global_group_limit || first.key === stage.resolved) {
if (snapshot.throttled) {
return guide.bypass_global_group_limit ? "returned" : "throttled";
Copy link

Choose a reason for hiding this comment

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

Missing includeThrottled check in selectAll status inference

Medium Severity

inferSelectAllByTypeReturnStatus doesn't check query.type?.all?.metadata?.opts?.includeThrottled before returning "throttled", unlike its sibling functions inferSelectByKeyReturnStatus and inferSelectOneByTypeReturnStatus which both respect this option. Since SelectGuidesOpts is aliased to SelectGuideOpts and the actual selectGuides client method uses includeThrottled to decide whether to filter out throttled guides, the toolbar will incorrectly show "throttled" for guides that are actually being returned when a consumer passes includeThrottled: true to useGuides.

Fix in Cursor Fix in Web

}
return "returned";
}

return "queried";
};

const inferSelectReturnStatus = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ describe("useInspectGuideClientStore", () => {
expect(annotated.annotation.selectable.status).toBe("queried");
});

test("selectable is 'returned' when queried by type (selectAll)", () => {
test("selectable is 'returned' when queried by type (selectAll) and guide is resolved", () => {
const guide = makeGuide({ key: "g1", type: "banner" });
mockGroupStage = {
status: "closed",
Expand All @@ -681,10 +681,215 @@ describe("useInspectGuideClientStore", () => {

const result = renderInspect()!;
const annotated = result.guides[0] as AnnotatedGuide;
// selectAll placeholder always returns "returned"
expect(annotated.annotation.selectable.status).toBe("returned");
});

test("selectAll: returns 'queried' when result is empty", () => {
const guide = makeGuide({ key: "g1", type: "banner" });
mockGroupStage = {
status: "closed",
ordered: ["g1"],
resolved: "g1",
timeoutId: null,
results: {
type: {
banner: {
all: makeSelectionResult([]),
},
},
},
};
setSnapshot({
guideGroups: [makeGuideGroup(["g1"])],
guides: { g1: guide },
});

const result = renderInspect()!;
const annotated = result.guides[0] as AnnotatedGuide;
expect(annotated.annotation.selectable.status).toBe("queried");
});

test("selectAll: returns 'returned' when first guide is unthrottled and not throttling", () => {
const guide = makeGuide({ key: "g1", type: "banner" });
mockGroupStage = {
status: "closed",
ordered: ["g1"],
resolved: "other",
timeoutId: null,
results: {
type: {
banner: {
all: makeSelectionResult([
[0, { key: "g1", bypass_global_group_limit: true }],
]),
},
},
},
};
setSnapshot({
guideGroups: [makeGuideGroup(["g1"])],
guides: { g1: guide },
});

const result = renderInspect()!;
const annotated = result.guides[0] as AnnotatedGuide;
expect(annotated.annotation.selectable.status).toBe("returned");
});

test("selectAll: returns 'returned' when throttled but guide bypasses group limit", () => {
mockCheckStateIfThrottled.mockReturnValue(true);
const guide = makeGuide({
key: "g1",
type: "banner",
bypass_global_group_limit: true,
});
mockGroupStage = {
status: "closed",
ordered: ["g1"],
resolved: "g1",
timeoutId: null,
results: {
type: {
banner: {
all: makeSelectionResult([[0, { key: "g1" }]]),
},
},
},
};
setSnapshot({
guideGroups: [makeGuideGroup(["g1"])],
guides: { g1: guide },
});

const result = renderInspect()!;
const annotated = result.guides[0] as AnnotatedGuide;
expect(annotated.annotation.selectable.status).toBe("returned");
});

test("selectAll: returns 'throttled' when throttled and guide does not bypass group limit", () => {
mockCheckStateIfThrottled.mockReturnValue(true);
const guide = makeGuide({
key: "g1",
type: "banner",
bypass_global_group_limit: false,
});
mockGroupStage = {
status: "closed",
ordered: ["g1"],
resolved: "g1",
timeoutId: null,
results: {
type: {
banner: {
all: makeSelectionResult([[0, { key: "g1" }]]),
},
},
},
};
setSnapshot({
guideGroups: [makeGuideGroup(["g1"])],
guides: { g1: guide },
});

const result = renderInspect()!;
const annotated = result.guides[0] as AnnotatedGuide;
expect(annotated.annotation.selectable.status).toBe("throttled");
});

test("selectAll: returns 'throttled' when first guide is unthrottled, throttled, and current guide is throttled", () => {
mockCheckStateIfThrottled.mockReturnValue(true);
const guide = makeGuide({
key: "g1",
type: "banner",
bypass_global_group_limit: false,
});
mockGroupStage = {
status: "closed",
ordered: ["g1"],
resolved: "other",
timeoutId: null,
results: {
type: {
banner: {
all: makeSelectionResult([
[0, { key: "first", bypass_global_group_limit: true }],
[1, { key: "g1", bypass_global_group_limit: false }],
]),
},
},
},
};
setSnapshot({
guideGroups: [makeGuideGroup(["g1"])],
guides: { g1: guide },
});

const result = renderInspect()!;
const annotated = result.guides[0] as AnnotatedGuide;
expect(annotated.annotation.selectable.status).toBe("throttled");
});

test("selectAll: returns 'returned' when first guide is unthrottled, throttled, and current guide bypasses group limit", () => {
mockCheckStateIfThrottled.mockReturnValue(true);
const guide = makeGuide({
key: "g1",
type: "banner",
bypass_global_group_limit: true,
});
mockGroupStage = {
status: "closed",
ordered: ["g1"],
resolved: "other",
timeoutId: null,
results: {
type: {
banner: {
all: makeSelectionResult([
[0, { key: "first", bypass_global_group_limit: true }],
[1, { key: "g1", bypass_global_group_limit: true }],
]),
},
},
},
};
setSnapshot({
guideGroups: [makeGuideGroup(["g1"])],
guides: { g1: guide },
});

const result = renderInspect()!;
const annotated = result.guides[0] as AnnotatedGuide;
expect(annotated.annotation.selectable.status).toBe("returned");
});

test("selectAll: returns 'queried' when first guide is neither resolved nor unthrottled", () => {
const guide = makeGuide({ key: "g1", type: "banner" });
mockGroupStage = {
status: "closed",
ordered: ["g1"],
resolved: "other",
timeoutId: null,
results: {
type: {
banner: {
all: makeSelectionResult([
[0, { key: "first", bypass_global_group_limit: false }],
[1, { key: "g1" }],
]),
},
},
},
};
setSnapshot({
guideGroups: [makeGuideGroup(["g1"])],
guides: { g1: guide },
});

const result = renderInspect()!;
const annotated = result.guides[0] as AnnotatedGuide;
expect(annotated.annotation.selectable.status).toBe("queried");
});

test("key-based query takes precedence over type-based query", () => {
const guide = makeGuide({ key: "g1", type: "banner" });
// Stage has both key and type results, key should take precedence
Expand Down
Loading