@yaebal/scenes 0.0.2 → 0.0.3
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/lib/index.test.js +41 -45
- package/lib/index.test.js.map +1 -1
- package/package.json +6 -5
- package/src/index.test.ts +54 -67
package/lib/index.test.js
CHANGED
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
|
-
import { Composer
|
|
3
|
+
import { Composer } from "@yaebal/core";
|
|
4
4
|
import { MemoryStorage } from "@yaebal/session";
|
|
5
|
+
import { createTestEnv } from "@yaebal/test";
|
|
5
6
|
import { scenes } from "./index.js";
|
|
6
|
-
const noop = async () => { };
|
|
7
|
-
const entry = (c) => c.toMiddleware();
|
|
8
|
-
const api = {};
|
|
9
|
-
const msgCtx = (text, chatId) => new Context({
|
|
10
|
-
api,
|
|
11
|
-
update: {
|
|
12
|
-
update_id: 1,
|
|
13
|
-
message: {
|
|
14
|
-
message_id: 1,
|
|
15
|
-
date: 0,
|
|
16
|
-
chat: { id: chatId, type: "private" },
|
|
17
|
-
from: { id: chatId, is_bot: false, first_name: "u" },
|
|
18
|
-
text,
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
updateType: "message",
|
|
22
|
-
});
|
|
23
7
|
test("a wizard collects input across messages and leaves", async () => {
|
|
24
8
|
const collected = {};
|
|
25
9
|
const asked = [];
|
|
@@ -43,30 +27,36 @@ test("a wizard collects input across messages and leaves", async () => {
|
|
|
43
27
|
};
|
|
44
28
|
const storage = new MemoryStorage();
|
|
45
29
|
let fellThrough = 0;
|
|
46
|
-
const
|
|
30
|
+
const bot = new Composer()
|
|
47
31
|
.install(scenes(defs, { storage }))
|
|
48
32
|
.command("reg", (ctx) => ctx.scene.enter("reg"))
|
|
49
33
|
.on("message:text", () => {
|
|
50
34
|
fellThrough++;
|
|
51
|
-
})
|
|
52
|
-
|
|
35
|
+
});
|
|
36
|
+
const env = createTestEnv(bot);
|
|
37
|
+
const user = env.createUser();
|
|
38
|
+
const key = String(user.pmChat.id);
|
|
39
|
+
await user.sendCommand("reg"); // enter → asks name
|
|
53
40
|
assert.deepEqual(asked, ["name?"]);
|
|
54
|
-
assert.deepEqual((await storage.get(
|
|
55
|
-
await
|
|
56
|
-
assert.equal(collected.name, "
|
|
57
|
-
assert.deepEqual((await storage.get(
|
|
58
|
-
await
|
|
41
|
+
assert.deepEqual((await storage.get(key)) ?? null, { scene: "reg", step: 0 });
|
|
42
|
+
await user.sendMessage("Linia"); // step 0 → name, advance, asks age
|
|
43
|
+
assert.equal(collected.name, "Linia");
|
|
44
|
+
assert.deepEqual((await storage.get(key)) ?? null, { scene: "reg", step: 1 });
|
|
45
|
+
await user.sendMessage("30"); // step 1 → age, leave
|
|
59
46
|
assert.equal(collected.age, "30");
|
|
60
|
-
assert.equal(await storage.get(
|
|
47
|
+
assert.equal(await storage.get(key), undefined); // scene cleared
|
|
61
48
|
// scene messages were consumed — the fallthrough handler never saw them
|
|
62
49
|
assert.equal(fellThrough, 0);
|
|
63
50
|
});
|
|
64
51
|
test("messages outside a scene fall through to normal handlers", async () => {
|
|
65
52
|
let seen = "";
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
53
|
+
const bot = new Composer()
|
|
54
|
+
.install(scenes({ reg: { steps: [] } }))
|
|
55
|
+
.on("message:text", (ctx) => {
|
|
56
|
+
seen = ctx.text ?? "";
|
|
57
|
+
});
|
|
58
|
+
const env = createTestEnv(bot);
|
|
59
|
+
await env.createUser().sendMessage("hello");
|
|
70
60
|
assert.equal(seen, "hello");
|
|
71
61
|
});
|
|
72
62
|
test("a step can switch scenes via enter()", async () => {
|
|
@@ -75,14 +65,17 @@ test("a step can switch scenes via enter()", async () => {
|
|
|
75
65
|
b: { steps: [(ctx) => ctx.scene.leave()] },
|
|
76
66
|
};
|
|
77
67
|
const storage = new MemoryStorage();
|
|
78
|
-
const
|
|
68
|
+
const bot = new Composer()
|
|
79
69
|
.install(scenes(defs, { storage }))
|
|
80
|
-
.command("a", (ctx) => ctx.scene.enter("a"))
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
await
|
|
85
|
-
|
|
70
|
+
.command("a", (ctx) => ctx.scene.enter("a"));
|
|
71
|
+
const env = createTestEnv(bot);
|
|
72
|
+
const user = env.createUser();
|
|
73
|
+
const key = String(user.pmChat.id);
|
|
74
|
+
await user.sendCommand("a"); // in scene a
|
|
75
|
+
await user.sendMessage("go"); // step a[0] → enter("b")
|
|
76
|
+
assert.deepEqual((await storage.get(key)) ?? null, { scene: "b", step: 0 });
|
|
77
|
+
await user.sendMessage("done"); // step b[0] → leave
|
|
78
|
+
assert.equal(await storage.get(key), undefined);
|
|
86
79
|
});
|
|
87
80
|
test("a step that does not advance re-runs (validation)", async () => {
|
|
88
81
|
let attempts = 0;
|
|
@@ -99,14 +92,17 @@ test("a step that does not advance re-runs (validation)", async () => {
|
|
|
99
92
|
},
|
|
100
93
|
};
|
|
101
94
|
const storage = new MemoryStorage();
|
|
102
|
-
const
|
|
95
|
+
const bot = new Composer()
|
|
103
96
|
.install(scenes(defs, { storage }))
|
|
104
|
-
.command("ask", (ctx) => ctx.scene.enter("ask"))
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
await
|
|
109
|
-
|
|
97
|
+
.command("ask", (ctx) => ctx.scene.enter("ask"));
|
|
98
|
+
const env = createTestEnv(bot);
|
|
99
|
+
const user = env.createUser();
|
|
100
|
+
const key = String(user.pmChat.id);
|
|
101
|
+
await user.sendCommand("ask");
|
|
102
|
+
await user.sendMessage("nope"); // stays
|
|
103
|
+
assert.deepEqual((await storage.get(key)) ?? null, { scene: "ask", step: 0 });
|
|
104
|
+
await user.sendMessage("ok"); // leaves
|
|
105
|
+
assert.equal(await storage.get(key), undefined);
|
|
110
106
|
assert.equal(attempts, 2);
|
|
111
107
|
});
|
|
112
108
|
//# sourceMappingURL=index.test.js.map
|
package/lib/index.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yaebal/scenes",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "yaebal scenes plugin — step-by-step wizards over multiple messages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
"src"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@yaebal/core": "0.0.
|
|
20
|
-
"@yaebal/session": "0.0.
|
|
19
|
+
"@yaebal/core": "0.0.8",
|
|
20
|
+
"@yaebal/session": "0.0.3"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/node": "latest"
|
|
23
|
+
"@types/node": "latest",
|
|
24
|
+
"@yaebal/test": "0.2.0"
|
|
24
25
|
},
|
|
25
26
|
"engines": {
|
|
26
27
|
"node": ">=20"
|
|
@@ -45,6 +46,6 @@
|
|
|
45
46
|
"scripts": {
|
|
46
47
|
"build": "tsc -p tsconfig.json",
|
|
47
48
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
48
|
-
"test": "node --test lib"
|
|
49
|
+
"test": "node --test lib/*.test.js"
|
|
49
50
|
}
|
|
50
51
|
}
|
package/src/index.test.ts
CHANGED
|
@@ -1,30 +1,10 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
|
-
import { Composer,
|
|
3
|
+
import { Composer, type Context } from "@yaebal/core";
|
|
4
4
|
import { MemoryStorage } from "@yaebal/session";
|
|
5
|
+
import { createTestEnv } from "@yaebal/test";
|
|
5
6
|
import { type SceneContext, type SceneDef, scenes } from "./index.js";
|
|
6
7
|
|
|
7
|
-
const noop = async () => {};
|
|
8
|
-
const entry = <C extends Context>(c: Composer<C>) =>
|
|
9
|
-
c.toMiddleware() as unknown as Middleware<Context>;
|
|
10
|
-
|
|
11
|
-
const api = {} as never;
|
|
12
|
-
const msgCtx = (text: string, chatId: number) =>
|
|
13
|
-
new Context({
|
|
14
|
-
api,
|
|
15
|
-
update: {
|
|
16
|
-
update_id: 1,
|
|
17
|
-
message: {
|
|
18
|
-
message_id: 1,
|
|
19
|
-
date: 0,
|
|
20
|
-
chat: { id: chatId, type: "private" },
|
|
21
|
-
from: { id: chatId, is_bot: false, first_name: "u" },
|
|
22
|
-
text,
|
|
23
|
-
},
|
|
24
|
-
} as never,
|
|
25
|
-
updateType: "message",
|
|
26
|
-
});
|
|
27
|
-
|
|
28
8
|
test("a wizard collects input across messages and leaves", async () => {
|
|
29
9
|
const collected: Record<string, string> = {};
|
|
30
10
|
const asked: string[] = [];
|
|
@@ -52,26 +32,28 @@ test("a wizard collects input across messages and leaves", async () => {
|
|
|
52
32
|
const storage = new MemoryStorage<{ scene: string; step: number }>();
|
|
53
33
|
let fellThrough = 0;
|
|
54
34
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
);
|
|
35
|
+
const bot = new Composer<Context>()
|
|
36
|
+
.install(scenes(defs, { storage }))
|
|
37
|
+
.command("reg", (ctx) => ctx.scene.enter("reg"))
|
|
38
|
+
.on("message:text", () => {
|
|
39
|
+
fellThrough++;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const env = createTestEnv(bot);
|
|
43
|
+
const user = env.createUser();
|
|
44
|
+
const key = String(user.pmChat.id);
|
|
63
45
|
|
|
64
|
-
await
|
|
46
|
+
await user.sendCommand("reg"); // enter → asks name
|
|
65
47
|
assert.deepEqual(asked, ["name?"]);
|
|
66
|
-
assert.deepEqual((await storage.get(
|
|
48
|
+
assert.deepEqual((await storage.get(key)) ?? null, { scene: "reg", step: 0 });
|
|
67
49
|
|
|
68
|
-
await
|
|
69
|
-
assert.equal(collected.name, "
|
|
70
|
-
assert.deepEqual((await storage.get(
|
|
50
|
+
await user.sendMessage("Linia"); // step 0 → name, advance, asks age
|
|
51
|
+
assert.equal(collected.name, "Linia");
|
|
52
|
+
assert.deepEqual((await storage.get(key)) ?? null, { scene: "reg", step: 1 });
|
|
71
53
|
|
|
72
|
-
await
|
|
54
|
+
await user.sendMessage("30"); // step 1 → age, leave
|
|
73
55
|
assert.equal(collected.age, "30");
|
|
74
|
-
assert.equal(await storage.get(
|
|
56
|
+
assert.equal(await storage.get(key), undefined); // scene cleared
|
|
75
57
|
|
|
76
58
|
// scene messages were consumed — the fallthrough handler never saw them
|
|
77
59
|
assert.equal(fellThrough, 0);
|
|
@@ -80,13 +62,14 @@ test("a wizard collects input across messages and leaves", async () => {
|
|
|
80
62
|
test("messages outside a scene fall through to normal handlers", async () => {
|
|
81
63
|
let seen = "";
|
|
82
64
|
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
65
|
+
const bot = new Composer<Context>()
|
|
66
|
+
.install(scenes({ reg: { steps: [] } }))
|
|
67
|
+
.on("message:text", (ctx) => {
|
|
68
|
+
seen = ctx.text ?? "";
|
|
69
|
+
});
|
|
88
70
|
|
|
89
|
-
|
|
71
|
+
const env = createTestEnv(bot);
|
|
72
|
+
await env.createUser().sendMessage("hello");
|
|
90
73
|
assert.equal(seen, "hello");
|
|
91
74
|
});
|
|
92
75
|
|
|
@@ -97,18 +80,20 @@ test("a step can switch scenes via enter()", async () => {
|
|
|
97
80
|
};
|
|
98
81
|
|
|
99
82
|
const storage = new MemoryStorage<{ scene: string; step: number }>();
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await
|
|
111
|
-
|
|
83
|
+
const bot = new Composer<Context>()
|
|
84
|
+
.install(scenes(defs, { storage }))
|
|
85
|
+
.command("a", (ctx) => ctx.scene.enter("a"));
|
|
86
|
+
|
|
87
|
+
const env = createTestEnv(bot);
|
|
88
|
+
const user = env.createUser();
|
|
89
|
+
const key = String(user.pmChat.id);
|
|
90
|
+
|
|
91
|
+
await user.sendCommand("a"); // in scene a
|
|
92
|
+
await user.sendMessage("go"); // step a[0] → enter("b")
|
|
93
|
+
assert.deepEqual((await storage.get(key)) ?? null, { scene: "b", step: 0 });
|
|
94
|
+
|
|
95
|
+
await user.sendMessage("done"); // step b[0] → leave
|
|
96
|
+
assert.equal(await storage.get(key), undefined);
|
|
112
97
|
});
|
|
113
98
|
|
|
114
99
|
test("a step that does not advance re-runs (validation)", async () => {
|
|
@@ -126,17 +111,19 @@ test("a step that does not advance re-runs (validation)", async () => {
|
|
|
126
111
|
};
|
|
127
112
|
|
|
128
113
|
const storage = new MemoryStorage<{ scene: string; step: number }>();
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
await
|
|
140
|
-
|
|
114
|
+
const bot = new Composer<Context>()
|
|
115
|
+
.install(scenes(defs, { storage }))
|
|
116
|
+
.command("ask", (ctx) => ctx.scene.enter("ask"));
|
|
117
|
+
|
|
118
|
+
const env = createTestEnv(bot);
|
|
119
|
+
const user = env.createUser();
|
|
120
|
+
const key = String(user.pmChat.id);
|
|
121
|
+
|
|
122
|
+
await user.sendCommand("ask");
|
|
123
|
+
await user.sendMessage("nope"); // stays
|
|
124
|
+
assert.deepEqual((await storage.get(key)) ?? null, { scene: "ask", step: 0 });
|
|
125
|
+
|
|
126
|
+
await user.sendMessage("ok"); // leaves
|
|
127
|
+
assert.equal(await storage.get(key), undefined);
|
|
141
128
|
assert.equal(attempts, 2);
|
|
142
129
|
});
|