diff --git a/actions/setup/js/add_labels.test.cjs b/actions/setup/js/add_labels.test.cjs index 3a233e043d7..c1f0e5bde2e 100644 --- a/actions/setup/js/add_labels.test.cjs +++ b/actions/setup/js/add_labels.test.cjs @@ -569,5 +569,86 @@ describe("add_labels", () => { expect(result.number).toBe(99); expect(addLabelsCalls[0].issue_number).toBe(99); }); + + it("should preview labels in staged mode without calling API", async () => { + const handler = await main({ max: 10, staged: true }); + const addLabelsCalls = []; + + mockGithub.rest.issues.addLabels = async params => { + addLabelsCalls.push(params); + return {}; + }; + + const result = await handler( + { + item_number: 100, + labels: ["bug", "enhancement"], + }, + {} + ); + + expect(result.success).toBe(true); + expect(result.staged).toBe(true); + expect(result.previewInfo).toBeDefined(); + expect(result.previewInfo.number).toBe(100); + expect(result.previewInfo.labels).toEqual(["bug", "enhancement"]); + expect(addLabelsCalls.length).toBe(0); + }); + + it("should count staged calls toward processedCount", async () => { + const handler = await main({ max: 1, staged: true }); + + const result1 = await handler({ item_number: 1, labels: ["bug"] }, {}); + expect(result1.success).toBe(true); + expect(result1.staged).toBe(true); + + const result2 = await handler({ item_number: 2, labels: ["enhancement"] }, {}); + expect(result2.success).toBe(false); + expect(result2.error).toContain("Max count"); + }); + + it("should filter out labels matching blocked patterns", async () => { + const handler = await main({ + max: 10, + blocked: ["internal-*", "~*"], + }); + const addLabelsCalls = []; + + mockGithub.rest.issues.addLabels = async params => { + addLabelsCalls.push(params); + return {}; + }; + + const result = await handler( + { + item_number: 100, + labels: ["bug", "internal-only", "~secret", "enhancement"], + }, + {} + ); + + expect(result.success).toBe(true); + expect(result.labelsAdded).toEqual(["bug", "enhancement"]); + expect(addLabelsCalls[0].labels).toEqual(["bug", "enhancement"]); + }); + + it("should succeed with empty labelsAdded when all labels filtered by allowed list", async () => { + const handler = await main({ + max: 10, + allowed: ["bug", "enhancement"], + }); + + const result = await handler( + { + item_number: 100, + labels: ["documentation", "invalid-label"], + }, + {} + ); + + expect(result.success).toBe(true); + expect(result.labelsAdded).toEqual([]); + expect(result.message).toContain("No valid labels"); + }); }); }); diff --git a/pkg/workflow/label_trigger_integration_test.go b/pkg/workflow/label_trigger_integration_test.go index cadb73df47d..549a0d2c6d6 100644 --- a/pkg/workflow/label_trigger_integration_test.go +++ b/pkg/workflow/label_trigger_integration_test.go @@ -88,8 +88,8 @@ func TestLabelTriggerIntegrationSimple(t *testing.T) { } required, ok := itemNumber["required"].(bool) - if !ok || !required { - t.Errorf("item_number.required = %v, want true", required) + if !ok || required { + t.Errorf("item_number.required = %v, want false", required) } }