agent-messenger 2.18.0 → 2.19.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/.claude-plugin/plugin.json +1 -1
- package/bunfig.toml +1 -0
- package/dist/package.json +1 -1
- package/dist/src/platforms/discordbot/client.d.ts +1 -0
- package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/client.js +3 -0
- package/dist/src/platforms/discordbot/client.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/message.d.ts +1 -0
- package/dist/src/platforms/discordbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/message.js +2 -0
- package/dist/src/platforms/discordbot/commands/message.js.map +1 -1
- package/dist/src/platforms/kakaotalk/client.d.ts +4 -2
- package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/client.js +67 -3
- package/dist/src/platforms/kakaotalk/client.js.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/message.js +23 -1
- package/dist/src/platforms/kakaotalk/commands/message.js.map +1 -1
- package/dist/src/platforms/kakaotalk/index.d.ts +1 -1
- package/dist/src/platforms/kakaotalk/index.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/index.js.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/session.d.ts +2 -1
- package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/session.js +15 -0
- package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
- package/dist/src/platforms/kakaotalk/types.d.ts +18 -0
- package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/types.js +1 -0
- package/dist/src/platforms/kakaotalk/types.js.map +1 -1
- package/dist/src/shared/chromium/browsers.js +1 -1
- package/dist/src/shared/chromium/browsers.js.map +1 -1
- package/docs/content/docs/cli/discordbot.mdx +6 -0
- package/docs/content/docs/sdk/discordbot.mdx +4 -0
- package/package.json +1 -1
- package/skills/agent-channeltalk/SKILL.md +1 -1
- package/skills/agent-channeltalkbot/SKILL.md +1 -1
- package/skills/agent-discord/SKILL.md +1 -1
- package/skills/agent-discordbot/SKILL.md +9 -1
- package/skills/agent-instagram/SKILL.md +1 -1
- package/skills/agent-kakaotalk/SKILL.md +24 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +1 -1
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +1 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-telegrambot/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +1 -1
- package/skills/agent-wechatbot/SKILL.md +1 -1
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/platforms/discord/commands/dm.test.ts +28 -20
- package/src/platforms/discord/commands/reaction.test.ts +12 -7
- package/src/platforms/discordbot/client.test.ts +17 -0
- package/src/platforms/discordbot/client.ts +9 -2
- package/src/platforms/discordbot/commands/message.test.ts +28 -11
- package/src/platforms/discordbot/commands/message.ts +4 -2
- package/src/platforms/instagram/commands/auth.test.ts +11 -9
- package/src/platforms/instagram/commands/chat.test.ts +8 -6
- package/src/platforms/instagram/commands/message.test.ts +8 -6
- package/src/platforms/kakaotalk/client.test.ts +96 -0
- package/src/platforms/kakaotalk/client.ts +82 -3
- package/src/platforms/kakaotalk/commands/message.test.ts +42 -0
- package/src/platforms/kakaotalk/commands/message.ts +33 -2
- package/src/platforms/kakaotalk/index.ts +2 -0
- package/src/platforms/kakaotalk/protocol/session.ts +15 -1
- package/src/platforms/kakaotalk/types.ts +24 -0
- package/src/platforms/webex/commands/auth.test.ts +30 -14
- package/src/platforms/webex/commands/member.test.ts +30 -34
- package/src/platforms/webex/commands/message.test.ts +37 -48
- package/src/platforms/webex/commands/snapshot.test.ts +26 -36
- package/src/platforms/webex/commands/space.test.ts +32 -38
- package/src/platforms/webex/commands/whoami.test.ts +10 -22
- package/src/platforms/webex/credential-manager.test.ts +3 -0
- package/src/platforms/whatsapp/commands/auth.test.ts +14 -20
- package/src/platforms/whatsapp/commands/chat.test.ts +17 -24
- package/src/platforms/whatsapp/commands/message.test.ts +31 -41
- package/src/shared/chromium/browsers.ts +1 -1
- package/src/test-setup.ts +5 -0
- package/tsconfig.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { afterEach, beforeEach, expect, spyOn, it } from 'bun:test'
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { WebexClient } from '../client'
|
|
4
4
|
import { WebexError } from '../types'
|
|
5
5
|
import { whoamiCommand } from './whoami'
|
|
6
6
|
|
|
@@ -17,27 +17,23 @@ const mockUser = {
|
|
|
17
17
|
created: '2024-01-01T00:00:00.000Z',
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return this
|
|
23
|
-
},
|
|
24
|
-
testAuth: async () => mockUser,
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
let webexClientSpy: ReturnType<typeof spyOn>
|
|
20
|
+
let loginSpy: ReturnType<typeof spyOn>
|
|
21
|
+
let testAuthSpy: ReturnType<typeof spyOn>
|
|
28
22
|
let consoleLogSpy: ReturnType<typeof spyOn>
|
|
29
23
|
let processExitSpy: ReturnType<typeof spyOn>
|
|
30
24
|
|
|
31
25
|
beforeEach(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
26
|
+
loginSpy = spyOn(WebexClient.prototype, 'login').mockImplementation(async function (this: WebexClient) {
|
|
27
|
+
return this
|
|
28
|
+
})
|
|
29
|
+
testAuthSpy = spyOn(WebexClient.prototype, 'testAuth').mockResolvedValue(mockUser)
|
|
35
30
|
consoleLogSpy = spyOn(console, 'log').mockImplementation(() => {})
|
|
36
31
|
processExitSpy = spyOn(process, 'exit').mockImplementation((_code?: number) => undefined as never)
|
|
37
32
|
})
|
|
38
33
|
|
|
39
34
|
afterEach(() => {
|
|
40
|
-
|
|
35
|
+
loginSpy?.mockRestore()
|
|
36
|
+
testAuthSpy?.mockRestore()
|
|
41
37
|
consoleLogSpy?.mockRestore()
|
|
42
38
|
processExitSpy?.mockRestore()
|
|
43
39
|
})
|
|
@@ -102,15 +98,7 @@ it('whoami outputs pretty-printed JSON when --pretty flag is passed', async () =
|
|
|
102
98
|
|
|
103
99
|
it('whoami exits with code 1 when not authenticated', async () => {
|
|
104
100
|
// given: no credentials
|
|
105
|
-
|
|
106
|
-
() =>
|
|
107
|
-
({
|
|
108
|
-
login: async () => {
|
|
109
|
-
throw new WebexError('No Webex credentials found.', 'no_credentials')
|
|
110
|
-
},
|
|
111
|
-
testAuth: async () => mockUser,
|
|
112
|
-
}) as unknown as clientModule.WebexClient,
|
|
113
|
-
)
|
|
101
|
+
loginSpy.mockRejectedValue(new WebexError('No Webex credentials found.', 'no_credentials'))
|
|
114
102
|
|
|
115
103
|
// when: running whoami
|
|
116
104
|
await whoamiCommand.parseAsync([], { from: 'user' })
|
|
@@ -8,6 +8,7 @@ import { WebexCredentialManager } from './credential-manager'
|
|
|
8
8
|
describe('WebexCredentialManager', () => {
|
|
9
9
|
let tempDir: string
|
|
10
10
|
let credManager: WebexCredentialManager
|
|
11
|
+
const realFetch = globalThis.fetch
|
|
11
12
|
|
|
12
13
|
beforeEach(async () => {
|
|
13
14
|
tempDir = await mkdtemp(join(tmpdir(), 'webex-cred-test-'))
|
|
@@ -16,6 +17,8 @@ describe('WebexCredentialManager', () => {
|
|
|
16
17
|
|
|
17
18
|
afterEach(async () => {
|
|
18
19
|
await rm(tempDir, { recursive: true, force: true })
|
|
20
|
+
// Guarantee fetch restoration even if a test throws before its own restore line.
|
|
21
|
+
globalThis.fetch = realFetch
|
|
19
22
|
})
|
|
20
23
|
|
|
21
24
|
it('loadConfig returns null when no file exists', async () => {
|
|
@@ -2,12 +2,6 @@ import { afterEach, beforeEach, describe, expect, mock, spyOn, it } from 'bun:te
|
|
|
2
2
|
|
|
3
3
|
const originalConsoleLog = console.log
|
|
4
4
|
|
|
5
|
-
mock.module('@/shared/utils/error-handler', () => ({
|
|
6
|
-
handleError: (err: Error) => {
|
|
7
|
-
throw err
|
|
8
|
-
},
|
|
9
|
-
}))
|
|
10
|
-
|
|
11
5
|
const mockGetAccount = mock(() => Promise.resolve(null))
|
|
12
6
|
const mockListAccounts = mock(() => Promise.resolve([]))
|
|
13
7
|
const mockSetCurrent = mock(() => Promise.resolve(false))
|
|
@@ -46,6 +40,7 @@ import { authCommand } from './auth'
|
|
|
46
40
|
|
|
47
41
|
describe('auth commands', () => {
|
|
48
42
|
let consoleLogSpy: ReturnType<typeof mock>
|
|
43
|
+
let consoleErrorSpy: ReturnType<typeof spyOn>
|
|
49
44
|
let processExitSpy: ReturnType<typeof spyOn>
|
|
50
45
|
|
|
51
46
|
beforeEach(() => {
|
|
@@ -73,14 +68,14 @@ describe('auth commands', () => {
|
|
|
73
68
|
|
|
74
69
|
consoleLogSpy = mock((..._args: unknown[]) => {})
|
|
75
70
|
console.log = consoleLogSpy
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
})
|
|
71
|
+
consoleErrorSpy = spyOn(console, 'error').mockImplementation(() => {})
|
|
72
|
+
processExitSpy = spyOn(process, 'exit').mockImplementation((_code?: number) => undefined as never)
|
|
79
73
|
processExitSpy.mockClear()
|
|
80
74
|
})
|
|
81
75
|
|
|
82
76
|
afterEach(() => {
|
|
83
77
|
console.log = originalConsoleLog
|
|
78
|
+
consoleErrorSpy.mockRestore()
|
|
84
79
|
processExitSpy.mockRestore()
|
|
85
80
|
})
|
|
86
81
|
|
|
@@ -153,7 +148,7 @@ describe('auth commands', () => {
|
|
|
153
148
|
it('outputs error and exits when account not found', async () => {
|
|
154
149
|
mockSetCurrent.mockImplementation(() => Promise.resolve(false))
|
|
155
150
|
|
|
156
|
-
await
|
|
151
|
+
await authCommand.parseAsync(['use', 'nonexistent'], { from: 'user' })
|
|
157
152
|
|
|
158
153
|
expect(processExitSpy).toHaveBeenCalledWith(1)
|
|
159
154
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
@@ -185,7 +180,7 @@ describe('auth commands', () => {
|
|
|
185
180
|
it('outputs error and exits when no account configured', async () => {
|
|
186
181
|
mockGetAccount.mockImplementation(() => Promise.resolve(null))
|
|
187
182
|
|
|
188
|
-
await
|
|
183
|
+
await authCommand.parseAsync(['status'], { from: 'user' })
|
|
189
184
|
|
|
190
185
|
expect(processExitSpy).toHaveBeenCalledWith(1)
|
|
191
186
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
@@ -217,9 +212,7 @@ describe('auth commands', () => {
|
|
|
217
212
|
it('outputs error for specific missing account', async () => {
|
|
218
213
|
mockGetAccount.mockImplementation(() => Promise.resolve(null))
|
|
219
214
|
|
|
220
|
-
await
|
|
221
|
-
'process.exit(1)',
|
|
222
|
-
)
|
|
215
|
+
await authCommand.parseAsync(['status', '--account', 'missing-id'], { from: 'user' })
|
|
223
216
|
|
|
224
217
|
expect(processExitSpy).toHaveBeenCalledWith(1)
|
|
225
218
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
@@ -241,8 +234,9 @@ describe('auth commands', () => {
|
|
|
241
234
|
)
|
|
242
235
|
mockRemoveAccount.mockImplementation(() => Promise.resolve(true))
|
|
243
236
|
|
|
244
|
-
await
|
|
237
|
+
await authCommand.parseAsync(['logout'], { from: 'user' })
|
|
245
238
|
|
|
239
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
246
240
|
expect(mockRemoveAccount).toHaveBeenCalledWith('plus-12025551234')
|
|
247
241
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
248
242
|
expect(output.success).toBe(true)
|
|
@@ -253,7 +247,7 @@ describe('auth commands', () => {
|
|
|
253
247
|
it('outputs error and exits when no account configured', async () => {
|
|
254
248
|
mockGetAccount.mockImplementation(() => Promise.resolve(null))
|
|
255
249
|
|
|
256
|
-
await
|
|
250
|
+
await authCommand.parseAsync(['logout'], { from: 'user' })
|
|
257
251
|
|
|
258
252
|
expect(processExitSpy).toHaveBeenCalledWith(1)
|
|
259
253
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
@@ -273,8 +267,9 @@ describe('auth commands', () => {
|
|
|
273
267
|
mockConnect.mockImplementation(() => Promise.reject(new Error('Connection failed')))
|
|
274
268
|
mockRemoveAccount.mockImplementation(() => Promise.resolve(true))
|
|
275
269
|
|
|
276
|
-
await
|
|
270
|
+
await authCommand.parseAsync(['logout'], { from: 'user' })
|
|
277
271
|
|
|
272
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
278
273
|
expect(mockRemoveAccount).toHaveBeenCalledWith('plus-12025551234')
|
|
279
274
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
280
275
|
expect(output.success).toBe(true)
|
|
@@ -295,10 +290,9 @@ describe('auth commands', () => {
|
|
|
295
290
|
})
|
|
296
291
|
mockRemoveAccount.mockImplementation(() => Promise.resolve(true))
|
|
297
292
|
|
|
298
|
-
await
|
|
299
|
-
authCommand.parseAsync(['logout', '--account', 'plus-19995551234'], { from: 'user' }),
|
|
300
|
-
).rejects.toThrow('process.exit(0)')
|
|
293
|
+
await authCommand.parseAsync(['logout', '--account', 'plus-19995551234'], { from: 'user' })
|
|
301
294
|
|
|
295
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
302
296
|
expect(mockRemoveAccount).toHaveBeenCalledWith('plus-19995551234')
|
|
303
297
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
304
298
|
expect(output.success).toBe(true)
|
|
@@ -2,12 +2,6 @@ import { afterEach, beforeEach, describe, expect, mock, spyOn, it } from 'bun:te
|
|
|
2
2
|
|
|
3
3
|
const originalConsoleLog = console.log
|
|
4
4
|
|
|
5
|
-
mock.module('@/shared/utils/error-handler', () => ({
|
|
6
|
-
handleError: (err: Error) => {
|
|
7
|
-
throw err
|
|
8
|
-
},
|
|
9
|
-
}))
|
|
10
|
-
|
|
11
5
|
const mockGetAccount = mock(() =>
|
|
12
6
|
Promise.resolve({
|
|
13
7
|
account_id: 'plus-12025551234',
|
|
@@ -69,6 +63,7 @@ import { chatCommand } from './chat'
|
|
|
69
63
|
|
|
70
64
|
describe('chat commands', () => {
|
|
71
65
|
let consoleLogSpy: ReturnType<typeof mock>
|
|
66
|
+
let consoleErrorSpy: ReturnType<typeof spyOn>
|
|
72
67
|
let processExitSpy: ReturnType<typeof spyOn>
|
|
73
68
|
|
|
74
69
|
beforeEach(() => {
|
|
@@ -118,21 +113,22 @@ describe('chat commands', () => {
|
|
|
118
113
|
|
|
119
114
|
consoleLogSpy = mock((..._args: unknown[]) => {})
|
|
120
115
|
console.log = consoleLogSpy
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
})
|
|
116
|
+
consoleErrorSpy = spyOn(console, 'error').mockImplementation(() => {})
|
|
117
|
+
processExitSpy = spyOn(process, 'exit').mockImplementation((_code?: number) => undefined as never)
|
|
124
118
|
processExitSpy.mockClear()
|
|
125
119
|
})
|
|
126
120
|
|
|
127
121
|
afterEach(() => {
|
|
128
122
|
console.log = originalConsoleLog
|
|
123
|
+
consoleErrorSpy.mockRestore()
|
|
129
124
|
processExitSpy.mockRestore()
|
|
130
125
|
})
|
|
131
126
|
|
|
132
127
|
describe('list', () => {
|
|
133
128
|
it('lists chats with default limit', async () => {
|
|
134
|
-
await
|
|
129
|
+
await chatCommand.parseAsync(['list'], { from: 'user' })
|
|
135
130
|
|
|
131
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
136
132
|
expect(mockListChats).toHaveBeenCalledWith(20)
|
|
137
133
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
138
134
|
expect(output).toHaveLength(1)
|
|
@@ -141,25 +137,23 @@ describe('chat commands', () => {
|
|
|
141
137
|
})
|
|
142
138
|
|
|
143
139
|
it('respects --limit option', async () => {
|
|
144
|
-
await
|
|
145
|
-
'process.exit(0)',
|
|
146
|
-
)
|
|
140
|
+
await chatCommand.parseAsync(['list', '--limit', '5'], { from: 'user' })
|
|
147
141
|
|
|
142
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
148
143
|
expect(mockListChats).toHaveBeenCalledWith(5)
|
|
149
144
|
})
|
|
150
145
|
|
|
151
146
|
it('passes account option to credential manager', async () => {
|
|
152
|
-
await
|
|
153
|
-
'process.exit(0)',
|
|
154
|
-
)
|
|
147
|
+
await chatCommand.parseAsync(['list', '--account', 'my-account'], { from: 'user' })
|
|
155
148
|
|
|
149
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
156
150
|
expect(mockGetAccount).toHaveBeenCalledWith('my-account')
|
|
157
151
|
})
|
|
158
152
|
|
|
159
153
|
it('exits with error when no account configured', async () => {
|
|
160
154
|
mockGetAccount.mockImplementation(() => Promise.resolve(null))
|
|
161
155
|
|
|
162
|
-
await
|
|
156
|
+
await chatCommand.parseAsync(['list'], { from: 'user' })
|
|
163
157
|
|
|
164
158
|
expect(processExitSpy).toHaveBeenCalledWith(1)
|
|
165
159
|
})
|
|
@@ -167,8 +161,9 @@ describe('chat commands', () => {
|
|
|
167
161
|
|
|
168
162
|
describe('search', () => {
|
|
169
163
|
it('searches chats by query', async () => {
|
|
170
|
-
await
|
|
164
|
+
await chatCommand.parseAsync(['search', 'Bob'], { from: 'user' })
|
|
171
165
|
|
|
166
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
172
167
|
expect(mockSearchChats).toHaveBeenCalledWith('Bob', 20)
|
|
173
168
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
174
169
|
expect(output).toHaveLength(1)
|
|
@@ -177,18 +172,16 @@ describe('chat commands', () => {
|
|
|
177
172
|
})
|
|
178
173
|
|
|
179
174
|
it('respects --limit option', async () => {
|
|
180
|
-
await
|
|
181
|
-
'process.exit(0)',
|
|
182
|
-
)
|
|
175
|
+
await chatCommand.parseAsync(['search', 'Alice', '--limit', '3'], { from: 'user' })
|
|
183
176
|
|
|
177
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
184
178
|
expect(mockSearchChats).toHaveBeenCalledWith('Alice', 3)
|
|
185
179
|
})
|
|
186
180
|
|
|
187
181
|
it('passes account option to credential manager', async () => {
|
|
188
|
-
await
|
|
189
|
-
chatCommand.parseAsync(['search', 'test', '--account', 'my-account'], { from: 'user' }),
|
|
190
|
-
).rejects.toThrow('process.exit(0)')
|
|
182
|
+
await chatCommand.parseAsync(['search', 'test', '--account', 'my-account'], { from: 'user' })
|
|
191
183
|
|
|
184
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
192
185
|
expect(mockGetAccount).toHaveBeenCalledWith('my-account')
|
|
193
186
|
})
|
|
194
187
|
})
|
|
@@ -2,12 +2,6 @@ import { afterEach, beforeEach, describe, expect, mock, spyOn, it } from 'bun:te
|
|
|
2
2
|
|
|
3
3
|
const originalConsoleLog = console.log
|
|
4
4
|
|
|
5
|
-
mock.module('@/shared/utils/error-handler', () => ({
|
|
6
|
-
handleError: (err: Error) => {
|
|
7
|
-
throw err
|
|
8
|
-
},
|
|
9
|
-
}))
|
|
10
|
-
|
|
11
5
|
const mockGetAccount = mock(() =>
|
|
12
6
|
Promise.resolve({
|
|
13
7
|
account_id: 'plus-12025551234',
|
|
@@ -69,6 +63,7 @@ import { messageCommand } from './message'
|
|
|
69
63
|
|
|
70
64
|
describe('message commands', () => {
|
|
71
65
|
let consoleLogSpy: ReturnType<typeof mock>
|
|
66
|
+
let consoleErrorSpy: ReturnType<typeof spyOn>
|
|
72
67
|
let processExitSpy: ReturnType<typeof spyOn>
|
|
73
68
|
|
|
74
69
|
beforeEach(() => {
|
|
@@ -118,23 +113,22 @@ describe('message commands', () => {
|
|
|
118
113
|
|
|
119
114
|
consoleLogSpy = mock((..._args: unknown[]) => {})
|
|
120
115
|
console.log = consoleLogSpy
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
})
|
|
116
|
+
consoleErrorSpy = spyOn(console, 'error').mockImplementation(() => {})
|
|
117
|
+
processExitSpy = spyOn(process, 'exit').mockImplementation((_code?: number) => undefined as never)
|
|
124
118
|
processExitSpy.mockClear()
|
|
125
119
|
})
|
|
126
120
|
|
|
127
121
|
afterEach(() => {
|
|
128
122
|
console.log = originalConsoleLog
|
|
123
|
+
consoleErrorSpy.mockRestore()
|
|
129
124
|
processExitSpy.mockRestore()
|
|
130
125
|
})
|
|
131
126
|
|
|
132
127
|
describe('list', () => {
|
|
133
128
|
it('fetches messages for a chat', async () => {
|
|
134
|
-
await
|
|
135
|
-
'process.exit(0)',
|
|
136
|
-
)
|
|
129
|
+
await messageCommand.parseAsync(['list', '12025551234@s.whatsapp.net'], { from: 'user' })
|
|
137
130
|
|
|
131
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
138
132
|
expect(mockGetMessages).toHaveBeenCalledWith('12025551234@s.whatsapp.net', 25)
|
|
139
133
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
140
134
|
expect(output).toHaveLength(1)
|
|
@@ -143,27 +137,25 @@ describe('message commands', () => {
|
|
|
143
137
|
})
|
|
144
138
|
|
|
145
139
|
it('respects --limit option', async () => {
|
|
146
|
-
await
|
|
147
|
-
messageCommand.parseAsync(['list', '12025551234@s.whatsapp.net', '--limit', '10'], { from: 'user' }),
|
|
148
|
-
).rejects.toThrow('process.exit(0)')
|
|
140
|
+
await messageCommand.parseAsync(['list', '12025551234@s.whatsapp.net', '--limit', '10'], { from: 'user' })
|
|
149
141
|
|
|
142
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
150
143
|
expect(mockGetMessages).toHaveBeenCalledWith('12025551234@s.whatsapp.net', 10)
|
|
151
144
|
})
|
|
152
145
|
|
|
153
146
|
it('passes account option to credential manager', async () => {
|
|
154
|
-
await
|
|
155
|
-
|
|
156
|
-
)
|
|
147
|
+
await messageCommand.parseAsync(['list', '12025551234@s.whatsapp.net', '--account', 'my-account'], {
|
|
148
|
+
from: 'user',
|
|
149
|
+
})
|
|
157
150
|
|
|
151
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
158
152
|
expect(mockGetAccount).toHaveBeenCalledWith('my-account')
|
|
159
153
|
})
|
|
160
154
|
|
|
161
155
|
it('exits with error when no account configured', async () => {
|
|
162
156
|
mockGetAccount.mockImplementation(() => Promise.resolve(null))
|
|
163
157
|
|
|
164
|
-
await
|
|
165
|
-
'process.exit(1)',
|
|
166
|
-
)
|
|
158
|
+
await messageCommand.parseAsync(['list', '12025551234@s.whatsapp.net'], { from: 'user' })
|
|
167
159
|
|
|
168
160
|
expect(processExitSpy).toHaveBeenCalledWith(1)
|
|
169
161
|
})
|
|
@@ -171,10 +163,9 @@ describe('message commands', () => {
|
|
|
171
163
|
|
|
172
164
|
describe('send', () => {
|
|
173
165
|
it('sends a message to a chat', async () => {
|
|
174
|
-
await
|
|
175
|
-
messageCommand.parseAsync(['send', '12025551234@s.whatsapp.net', 'Hello world'], { from: 'user' }),
|
|
176
|
-
).rejects.toThrow('process.exit(0)')
|
|
166
|
+
await messageCommand.parseAsync(['send', '12025551234@s.whatsapp.net', 'Hello world'], { from: 'user' })
|
|
177
167
|
|
|
168
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
178
169
|
expect(mockSendMessage).toHaveBeenCalledWith('12025551234@s.whatsapp.net', 'Hello world')
|
|
179
170
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
180
171
|
expect(output.id).toBe('msg-2')
|
|
@@ -182,22 +173,20 @@ describe('message commands', () => {
|
|
|
182
173
|
})
|
|
183
174
|
|
|
184
175
|
it('passes account option to credential manager', async () => {
|
|
185
|
-
await
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}),
|
|
189
|
-
).rejects.toThrow('process.exit(0)')
|
|
176
|
+
await messageCommand.parseAsync(['send', '12025551234@s.whatsapp.net', 'Hi', '--account', 'my-account'], {
|
|
177
|
+
from: 'user',
|
|
178
|
+
})
|
|
190
179
|
|
|
180
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
191
181
|
expect(mockGetAccount).toHaveBeenCalledWith('my-account')
|
|
192
182
|
})
|
|
193
183
|
})
|
|
194
184
|
|
|
195
185
|
describe('react', () => {
|
|
196
186
|
it('sends a reaction to a message', async () => {
|
|
197
|
-
await
|
|
198
|
-
messageCommand.parseAsync(['react', '12025551234@s.whatsapp.net', 'msg-1', '👍'], { from: 'user' }),
|
|
199
|
-
).rejects.toThrow('process.exit(0)')
|
|
187
|
+
await messageCommand.parseAsync(['react', '12025551234@s.whatsapp.net', 'msg-1', '👍'], { from: 'user' })
|
|
200
188
|
|
|
189
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
201
190
|
expect(mockSendReaction).toHaveBeenCalledWith('12025551234@s.whatsapp.net', 'msg-1', '👍', undefined)
|
|
202
191
|
const output = JSON.parse(consoleLogSpy.mock.calls[0][0])
|
|
203
192
|
expect(output.success).toBe(true)
|
|
@@ -207,22 +196,23 @@ describe('message commands', () => {
|
|
|
207
196
|
})
|
|
208
197
|
|
|
209
198
|
it('passes --from-me flag to sendReaction', async () => {
|
|
210
|
-
await
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}),
|
|
214
|
-
).rejects.toThrow('process.exit(0)')
|
|
199
|
+
await messageCommand.parseAsync(['react', '12025551234@s.whatsapp.net', 'msg-1', '❤️', '--from-me'], {
|
|
200
|
+
from: 'user',
|
|
201
|
+
})
|
|
215
202
|
|
|
203
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
216
204
|
expect(mockSendReaction).toHaveBeenCalledWith('12025551234@s.whatsapp.net', 'msg-1', '❤️', true)
|
|
217
205
|
})
|
|
218
206
|
|
|
219
207
|
it('passes account option to credential manager', async () => {
|
|
220
|
-
await
|
|
221
|
-
|
|
208
|
+
await messageCommand.parseAsync(
|
|
209
|
+
['react', '12025551234@s.whatsapp.net', 'msg-1', '👍', '--account', 'my-account'],
|
|
210
|
+
{
|
|
222
211
|
from: 'user',
|
|
223
|
-
}
|
|
224
|
-
)
|
|
212
|
+
},
|
|
213
|
+
)
|
|
225
214
|
|
|
215
|
+
expect(processExitSpy).toHaveBeenCalledWith(0)
|
|
226
216
|
expect(mockGetAccount).toHaveBeenCalledWith('my-account')
|
|
227
217
|
})
|
|
228
218
|
})
|
|
@@ -75,7 +75,7 @@ export function discoverBrowserProfileDirs(browserBase: string): string[] {
|
|
|
75
75
|
dirs.push(join(browserBase, 'Default'))
|
|
76
76
|
if (!existsSync(browserBase)) return dirs
|
|
77
77
|
try {
|
|
78
|
-
const entries = readdirSync(browserBase, { withFileTypes: true })
|
|
78
|
+
const entries = readdirSync(browserBase, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))
|
|
79
79
|
for (const entry of entries) {
|
|
80
80
|
if (!entry.isDirectory()) continue
|
|
81
81
|
if (!/^Profile \d+$/i.test(entry.name)) continue
|
package/tsconfig.json
CHANGED