fix(nextcloud-talk): centralize integer coercion · openclaw/openclaw@ed59629
steipete
·
2026-05-29
·
via Recent Commits to openclaw:main
File tree
extensions/nextcloud-talk/src
| Original file line number | Diff line number | Diff line change |
|---|
@@ -80,6 +80,19 @@ describe("probeNextcloudTalkBotResponseFeature", () => {
|
80 | 80 | }); |
81 | 81 | }); |
82 | 82 | |
| 83 | +it("normalizes signed decimal bot feature strings through the shared parser", async () => { |
| 84 | +mockBotAdmin("+011"); |
| 85 | + |
| 86 | +await expect(probeNextcloudTalkBotResponseFeature({ account: account() })).resolves.toEqual({ |
| 87 | +ok: true, |
| 88 | +code: "ok", |
| 89 | +botId: "7", |
| 90 | +botName: "OpenClaw", |
| 91 | +features: 11, |
| 92 | +message: 'Nextcloud Talk bot "OpenClaw" has the response feature.', |
| 93 | +}); |
| 94 | +}); |
| 95 | + |
83 | 96 | it("reports missing response feature for the matching webhook bot", async () => { |
84 | 97 | mockBotAdmin(1 | 8); |
85 | 98 | |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
1 | 1 | import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime"; |
| 2 | +import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime"; |
2 | 3 | import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http"; |
3 | 4 | import { fetchWithSsrFGuard } from "../runtime-api.js"; |
4 | 5 | import type { ResolvedNextcloudTalkAccount } from "./accounts.js"; |
@@ -50,11 +51,7 @@ function coerceFeatureMask(value: unknown): number | undefined {
|
50 | 51 | if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) { |
51 | 52 | return value; |
52 | 53 | } |
53 | | -if (typeof value === "string" && /^[+-]?\d+$/.test(value.trim())) { |
54 | | -const parsed = Number(value.trim()); |
55 | | -return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : undefined; |
56 | | -} |
57 | | -return undefined; |
| 54 | +return parseStrictNonNegativeInteger(value); |
58 | 55 | } |
59 | 56 | |
60 | 57 | function formatMissingResponseFeatureMessage(bot: NextcloudTalkBotAdminEntry, features?: number) { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -73,6 +73,36 @@ describe("nextcloud talk room info", () => {
|
73 | 73 | expect(release).toHaveBeenCalledTimes(1); |
74 | 74 | }); |
75 | 75 | |
| 76 | +it("normalizes signed decimal room type strings through the shared parser", async () => { |
| 77 | +fetchWithSsrFGuard.mockResolvedValue({ |
| 78 | +response: { |
| 79 | +ok: true, |
| 80 | +json: async () => ({ |
| 81 | +ocs: { |
| 82 | +data: { |
| 83 | +type: "+01", |
| 84 | +}, |
| 85 | +}, |
| 86 | +}), |
| 87 | +}, |
| 88 | +release: vi.fn(async () => {}), |
| 89 | +}); |
| 90 | + |
| 91 | +await expect( |
| 92 | +resolveNextcloudTalkRoomKind({ |
| 93 | +account: { |
| 94 | +accountId: "acct-direct-string", |
| 95 | +baseUrl: "https://nc.example.com", |
| 96 | +config: { |
| 97 | +apiUser: "bot", |
| 98 | +apiPassword: "secret", |
| 99 | +}, |
| 100 | +} as never, |
| 101 | +roomToken: "room-direct-string", |
| 102 | +}), |
| 103 | +).resolves.toBe("direct"); |
| 104 | +}); |
| 105 | + |
76 | 106 | it("does not coerce partial room type strings", async () => { |
77 | 107 | fetchWithSsrFGuard.mockResolvedValue({ |
78 | 108 | response: { |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
1 | 1 | import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime"; |
| 2 | +import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime"; |
2 | 3 | import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http"; |
3 | 4 | import { ssrfPolicyFromPrivateNetworkOptIn } from "openclaw/plugin-sdk/ssrf-runtime"; |
4 | 5 | import { fetchWithSsrFGuard, type RuntimeEnv } from "../runtime-api.js"; |
@@ -27,11 +28,7 @@ function coerceRoomType(value: unknown): number | undefined {
|
27 | 28 | if (typeof value === "number" && Number.isSafeInteger(value) && value > 0) { |
28 | 29 | return value; |
29 | 30 | } |
30 | | -if (typeof value === "string" && /^[+-]?\d+$/.test(value.trim())) { |
31 | | -const parsed = Number(value.trim()); |
32 | | -return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined; |
33 | | -} |
34 | | -return undefined; |
| 31 | +return parseStrictPositiveInteger(value); |
35 | 32 | } |
36 | 33 | |
37 | 34 | function resolveRoomKindFromType(type: number | undefined): "direct" | "group" | undefined { |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。