惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
小众软件
小众软件
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
Jina AI
Jina AI
博客园 - 【当耐特】
V
Visual Studio Blog
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
量子位
IT之家
IT之家
G
Google Developers Blog
V
V2EX
The GitHub Blog
The GitHub Blog
月光博客
月光博客
GbyAI
GbyAI

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
test: tighten apns relay assertions · openclaw/openclaw@d...
steipete · 2026-05-11 · via Recent Commits to openclaw:main

@@ -42,6 +42,18 @@ function createRelayPushParams() {

4242

};

4343

}

444445+

function expectRelayConfig(

46+

resolved: ReturnType<typeof resolveApnsRelayConfigFromEnv>,

47+

expected: { baseUrl: string; timeoutMs: number },

48+

) {

49+

expect(resolved.ok).toBe(true);

50+

if (!resolved.ok) {

51+

throw new Error("expected APNs relay config to resolve");

52+

}

53+

expect(resolved.value.baseUrl).toBe(expected.baseUrl);

54+

expect(resolved.value.timeoutMs).toBe(expected.timeoutMs);

55+

}

56+4557

describe("push-apns.relay", () => {

4658

describe("resolveApnsRelayConfigFromEnv", () => {

4759

it("returns a missing-config error when no relay base URL is configured", () => {

@@ -70,12 +82,9 @@ describe("push-apns.relay", () => {

7082

},

7183

);

728473-

expect(resolved).toMatchObject({

74-

ok: true,

75-

value: {

76-

baseUrl: "https://relay-override.example.com/base",

77-

timeoutMs: 1000,

78-

},

85+

expectRelayConfig(resolved, {

86+

baseUrl: "https://relay-override.example.com/base",

87+

timeoutMs: 1000,

7988

});

8089

});

8190

@@ -86,12 +95,9 @@ describe("push-apns.relay", () => {

8695

OPENCLAW_APNS_RELAY_TIMEOUT_MS: "nope",

8796

} as NodeJS.ProcessEnv);

889789-

expect(resolved).toMatchObject({

90-

ok: true,

91-

value: {

92-

baseUrl: "http://[::1]:8787",

93-

timeoutMs: 10_000,

94-

},

98+

expectRelayConfig(resolved, {

99+

baseUrl: "http://[::1]:8787",

100+

timeoutMs: 10_000,

95101

});

96102

});

97103

@@ -154,20 +160,29 @@ describe("push-apns.relay", () => {

154160

});

155161156162

expect(sender).toHaveBeenCalledTimes(1);

157-

const sent = sender.mock.calls[0]?.[0];

158-

expect(sent).toMatchObject({

159-

relayConfig: {

160-

baseUrl: "https://relay.example.com",

161-

timeoutMs: 1000,

162-

},

163-

sendGrant: "send-grant-123",

164-

relayHandle: "relay-handle-123",

165-

gatewayDeviceId: relayGatewayIdentity.deviceId,

166-

signedAtMs: 123_456_789,

167-

pushType: "alert",

168-

priority: "10",

169-

payload: { aps: { alert: { title: "Wake", body: "Ping" } } },

170-

});

163+

const sent = sender.mock.calls[0]?.[0] as

164+

| {

165+

relayConfig?: { baseUrl?: string; timeoutMs?: number };

166+

sendGrant?: string;

167+

relayHandle?: string;

168+

gatewayDeviceId?: string;

169+

signedAtMs?: number;

170+

pushType?: string;

171+

priority?: string;

172+

payload?: unknown;

173+

bodyJson?: string;

174+

signature?: string;

175+

}

176+

| undefined;

177+

expect(sent?.relayConfig?.baseUrl).toBe("https://relay.example.com");

178+

expect(sent?.relayConfig?.timeoutMs).toBe(1000);

179+

expect(sent?.sendGrant).toBe("send-grant-123");

180+

expect(sent?.relayHandle).toBe("relay-handle-123");

181+

expect(sent?.gatewayDeviceId).toBe(relayGatewayIdentity.deviceId);

182+

expect(sent?.signedAtMs).toBe(123_456_789);

183+

expect(sent?.pushType).toBe("alert");

184+

expect(sent?.priority).toBe("10");

185+

expect(sent?.payload).toEqual({ aps: { alert: { title: "Wake", body: "Ping" } } });

171186

expect(sent?.bodyJson).toBe(

172187

JSON.stringify({

173188

relayHandle: "relay-handle-123",

@@ -188,13 +203,11 @@ describe("push-apns.relay", () => {

188203

sent?.signature ?? "",

189204

),

190205

).toBe(true);

191-

expect(result).toMatchObject({

192-

ok: true,

193-

status: 200,

194-

apnsId: "relay-apns-id",

195-

environment: "production",

196-

tokenSuffix: "abcd1234",

197-

});

206+

expect(result.ok).toBe(true);

207+

expect(result.status).toBe(200);

208+

expect(result.apnsId).toBe("relay-apns-id");

209+

expect(result.environment).toBe("production");

210+

expect(result.tokenSuffix).toBe("abcd1234");

198211

});

199212200213

it("does not follow relay redirects", async () => {

@@ -208,13 +221,12 @@ describe("push-apns.relay", () => {

208221

const result = await sendApnsRelayPush(createRelayPushParams());

209222210223

expect(fetchMock).toHaveBeenCalledTimes(1);

211-

expect(fetchMock.mock.calls[0]?.[1]).toMatchObject({ redirect: "manual" });

212-

expect(result).toMatchObject({

213-

ok: false,

214-

status: 302,

215-

reason: "RelayRedirectNotAllowed",

216-

environment: "production",

217-

});

224+

const fetchOptions = fetchMock.mock.calls[0]?.[1] as { redirect?: unknown } | undefined;

225+

expect(fetchOptions?.redirect).toBe("manual");

226+

expect(result.ok).toBe(false);

227+

expect(result.status).toBe(302);

228+

expect(result.reason).toBe("RelayRedirectNotAllowed");

229+

expect(result.environment).toBe("production");

218230

});

219231220232

it("falls back to fetch status when the relay body is not JSON", async () => {