@bytesbrains/pi-telegram-bridge 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/__tests__/helpers.test.ts +783 -0
- package/src/__tests__/index.test.ts +559 -0
- package/src/__tests__/tools.test.ts +251 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-telegram-bridge — Tool Schema Tests
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from "vitest";
|
|
5
|
+
import { Value } from "typebox/value";
|
|
6
|
+
import {
|
|
7
|
+
listenSchema,
|
|
8
|
+
sendSchema,
|
|
9
|
+
askSchema,
|
|
10
|
+
statusSchema,
|
|
11
|
+
overrideSchema,
|
|
12
|
+
} from "../tools/telegram";
|
|
13
|
+
|
|
14
|
+
// ── listenSchema ──────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
describe("listenSchema", () => {
|
|
17
|
+
it("accepts empty object", () => {
|
|
18
|
+
expect(Value.Check(listenSchema, {})).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("still checks ok with extra properties (by default)", () => {
|
|
22
|
+
// TypeBox Object doesn't strip extra by default unless additionalProperties: false
|
|
23
|
+
expect(Value.Check(listenSchema, { extra: 1 })).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// ── sendSchema ────────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
describe("sendSchema", () => {
|
|
30
|
+
it("accepts valid message", () => {
|
|
31
|
+
expect(Value.Check(sendSchema, { message: "Hello" })).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("accepts empty message", () => {
|
|
35
|
+
expect(Value.Check(sendSchema, { message: "" })).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("rejects missing message", () => {
|
|
39
|
+
expect(Value.Check(sendSchema, {})).toBe(false);
|
|
40
|
+
expect(Value.Check(sendSchema, { message: 123 })).toBe(false);
|
|
41
|
+
expect(Value.Check(sendSchema, { message: null })).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("accepts long messages", () => {
|
|
45
|
+
expect(Value.Check(sendSchema, { message: "x".repeat(4096) })).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// ── askSchema ─────────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
describe("askSchema", () => {
|
|
52
|
+
it("accepts minimal valid input (question only)", () => {
|
|
53
|
+
expect(Value.Check(askSchema, { question: "Deploy?" })).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("accepts question with options", () => {
|
|
57
|
+
expect(
|
|
58
|
+
Value.Check(askSchema, {
|
|
59
|
+
question: "Which?",
|
|
60
|
+
options: ["A", "B", "C"],
|
|
61
|
+
}),
|
|
62
|
+
).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("accepts question with timeoutMinutes", () => {
|
|
66
|
+
expect(
|
|
67
|
+
Value.Check(askSchema, {
|
|
68
|
+
question: "Go?",
|
|
69
|
+
timeoutMinutes: 5,
|
|
70
|
+
}),
|
|
71
|
+
).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("accepts all fields", () => {
|
|
75
|
+
expect(
|
|
76
|
+
Value.Check(askSchema, {
|
|
77
|
+
question: "Full test",
|
|
78
|
+
options: ["Yes", "No"],
|
|
79
|
+
timeoutMinutes: 10,
|
|
80
|
+
}),
|
|
81
|
+
).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("rejects missing question", () => {
|
|
85
|
+
expect(Value.Check(askSchema, {})).toBe(false);
|
|
86
|
+
expect(Value.Check(askSchema, { question: 123 })).toBe(false);
|
|
87
|
+
expect(Value.Check(askSchema, { options: ["A"] })).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("accepts empty options array", () => {
|
|
91
|
+
expect(
|
|
92
|
+
Value.Check(askSchema, {
|
|
93
|
+
question: "test",
|
|
94
|
+
options: [],
|
|
95
|
+
}),
|
|
96
|
+
).toBe(true);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("rejects non-array options", () => {
|
|
100
|
+
expect(
|
|
101
|
+
Value.Check(askSchema, {
|
|
102
|
+
question: "test",
|
|
103
|
+
options: "not-array",
|
|
104
|
+
}),
|
|
105
|
+
).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("rejects non-number timeoutMinutes", () => {
|
|
109
|
+
expect(
|
|
110
|
+
Value.Check(askSchema, {
|
|
111
|
+
question: "test",
|
|
112
|
+
timeoutMinutes: "30",
|
|
113
|
+
}),
|
|
114
|
+
).toBe(false);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("accepts timeoutMinutes as 0", () => {
|
|
118
|
+
expect(
|
|
119
|
+
Value.Check(askSchema, {
|
|
120
|
+
question: "test",
|
|
121
|
+
timeoutMinutes: 0,
|
|
122
|
+
}),
|
|
123
|
+
).toBe(true);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// ── statusSchema ──────────────────────────────────────────────────
|
|
128
|
+
|
|
129
|
+
describe("statusSchema", () => {
|
|
130
|
+
it("accepts empty object", () => {
|
|
131
|
+
expect(Value.Check(statusSchema, {})).toBe(true);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// ── overrideSchema ────────────────────────────────────────────────
|
|
136
|
+
|
|
137
|
+
describe("overrideSchema", () => {
|
|
138
|
+
it("accepts required fields only", () => {
|
|
139
|
+
expect(
|
|
140
|
+
Value.Check(overrideSchema, {
|
|
141
|
+
command: "git push --force",
|
|
142
|
+
reason: "Force push detected",
|
|
143
|
+
}),
|
|
144
|
+
).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("rejects missing command", () => {
|
|
148
|
+
expect(
|
|
149
|
+
Value.Check(overrideSchema, {
|
|
150
|
+
reason: "test",
|
|
151
|
+
}),
|
|
152
|
+
).toBe(false);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("rejects missing reason", () => {
|
|
156
|
+
expect(
|
|
157
|
+
Value.Check(overrideSchema, {
|
|
158
|
+
command: "rm -rf /",
|
|
159
|
+
}),
|
|
160
|
+
).toBe(false);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("accepts all optional fields", () => {
|
|
164
|
+
expect(
|
|
165
|
+
Value.Check(overrideSchema, {
|
|
166
|
+
command: "rm -rf node_modules",
|
|
167
|
+
reason: "Outside project boundary",
|
|
168
|
+
context: "User requested clean reinstall",
|
|
169
|
+
options: ["Yes", "No", "Maybe", "Explain"],
|
|
170
|
+
timeoutMinutes: 15,
|
|
171
|
+
}),
|
|
172
|
+
).toBe(true);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("accepts empty options array", () => {
|
|
176
|
+
expect(
|
|
177
|
+
Value.Check(overrideSchema, {
|
|
178
|
+
command: "test",
|
|
179
|
+
reason: "test",
|
|
180
|
+
options: [],
|
|
181
|
+
}),
|
|
182
|
+
).toBe(true);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it("rejects non-string command", () => {
|
|
186
|
+
expect(
|
|
187
|
+
Value.Check(overrideSchema, {
|
|
188
|
+
command: 123,
|
|
189
|
+
reason: "test",
|
|
190
|
+
}),
|
|
191
|
+
).toBe(false);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it("rejects non-string reason", () => {
|
|
195
|
+
expect(
|
|
196
|
+
Value.Check(overrideSchema, {
|
|
197
|
+
command: "test",
|
|
198
|
+
reason: null,
|
|
199
|
+
}),
|
|
200
|
+
).toBe(false);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("rejects non-string context", () => {
|
|
204
|
+
expect(
|
|
205
|
+
Value.Check(overrideSchema, {
|
|
206
|
+
command: "test",
|
|
207
|
+
reason: "test",
|
|
208
|
+
context: 123,
|
|
209
|
+
}),
|
|
210
|
+
).toBe(false);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("rejects non-array options", () => {
|
|
214
|
+
expect(
|
|
215
|
+
Value.Check(overrideSchema, {
|
|
216
|
+
command: "test",
|
|
217
|
+
reason: "test",
|
|
218
|
+
options: "yes,no",
|
|
219
|
+
}),
|
|
220
|
+
).toBe(false);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it("rejects non-number timeoutMinutes", () => {
|
|
224
|
+
expect(
|
|
225
|
+
Value.Check(overrideSchema, {
|
|
226
|
+
command: "test",
|
|
227
|
+
reason: "test",
|
|
228
|
+
timeoutMinutes: "10",
|
|
229
|
+
}),
|
|
230
|
+
).toBe(false);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("accepts timeoutMinutes as 0", () => {
|
|
234
|
+
expect(
|
|
235
|
+
Value.Check(overrideSchema, {
|
|
236
|
+
command: "test",
|
|
237
|
+
reason: "test",
|
|
238
|
+
timeoutMinutes: 0,
|
|
239
|
+
}),
|
|
240
|
+
).toBe(true);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("accepts long command and reason strings", () => {
|
|
244
|
+
expect(
|
|
245
|
+
Value.Check(overrideSchema, {
|
|
246
|
+
command: "x".repeat(1000),
|
|
247
|
+
reason: "y".repeat(1000),
|
|
248
|
+
}),
|
|
249
|
+
).toBe(true);
|
|
250
|
+
});
|
|
251
|
+
});
|