























@@ -1,10 +1,11 @@
1-import { describe, expect, it } from "vitest";
1+import { describe, expect, it, vi } from "vitest";
22import {
33MOCK_ONLY_PROOF_LABEL,
44NEEDS_REAL_BEHAVIOR_PROOF_LABEL,
55PROOF_OVERRIDE_LABEL,
66PROOF_SUPPLIED_LABEL,
77evaluateRealBehaviorProof,
8+isMaintainerTeamMember,
89labelsForRealBehaviorProof,
910} from "../../scripts/github/real-behavior-proof-policy.mjs";
1011@@ -174,3 +175,59 @@ describe("real-behavior-proof-policy", () => {
174175).toBe("override");
175176});
176177});
178+179+describe("isMaintainerTeamMember", () => {
180+function jsonResponse(status: number, body: unknown = {}) {
181+return {
182+ok: status >= 200 && status < 300,
183+ status,
184+json: () => Promise.resolve(body),
185+};
186+}
187+188+it("returns true for active members", async () => {
189+const fetch = vi.fn().mockResolvedValue(jsonResponse(200, { state: "active" }));
190+const result = await isMaintainerTeamMember({
191+token: "tok",
192+org: "openclaw",
193+login: "private-maint",
194+ fetch,
195+});
196+197+expect(result).toBe(true);
198+expect(fetch).toHaveBeenCalledWith(
199+"https://api.github.com/orgs/openclaw/teams/maintainer/memberships/private-maint",
200+expect.objectContaining({
201+headers: expect.objectContaining({
202+Authorization: "Bearer tok",
203+Accept: "application/vnd.github+json",
204+}),
205+}),
206+);
207+});
208+209+it("returns false for non-active membership states", async () => {
210+const fetch = vi.fn().mockResolvedValue(jsonResponse(200, { state: "pending" }));
211+expect(await isMaintainerTeamMember({ token: "t", org: "o", login: "u", fetch })).toBe(false);
212+});
213+214+it("returns false when GitHub returns 404", async () => {
215+const fetch = vi.fn().mockResolvedValue(jsonResponse(404));
216+expect(await isMaintainerTeamMember({ token: "t", org: "o", login: "u", fetch })).toBe(false);
217+});
218+219+it("returns false when the token, org, or login is missing", async () => {
220+const fetch = vi.fn();
221+expect(await isMaintainerTeamMember({ org: "o", login: "u", fetch })).toBe(false);
222+expect(await isMaintainerTeamMember({ token: "t", login: "u", fetch })).toBe(false);
223+expect(await isMaintainerTeamMember({ token: "t", org: "o", fetch })).toBe(false);
224+expect(fetch).not.toHaveBeenCalled();
225+});
226+227+it("throws on unexpected HTTP errors so the caller can warn and fall back", async () => {
228+const fetch = vi.fn().mockResolvedValue(jsonResponse(500));
229+await expect(
230+isMaintainerTeamMember({ token: "t", org: "o", login: "u", fetch }),
231+).rejects.toThrow(/500/);
232+});
233+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。