agent-messenger 2.10.1 → 2.10.2
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/dist/package.json +1 -1
- package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/teams/token-extractor.js +9 -2
- package/dist/src/platforms/teams/token-extractor.js.map +1 -1
- package/dist/src/shared/chromium/decryptor.d.ts +6 -0
- package/dist/src/shared/chromium/decryptor.d.ts.map +1 -1
- package/dist/src/shared/chromium/decryptor.js +26 -6
- package/dist/src/shared/chromium/decryptor.js.map +1 -1
- package/e2e/channeltalk.e2e.test.ts +13 -13
- package/e2e/channeltalkbot.e2e.test.ts +13 -13
- package/e2e/discord.e2e.test.ts +24 -24
- package/e2e/discordbot.e2e.test.ts +16 -16
- package/e2e/instagram.e2e.test.ts +10 -10
- package/e2e/kakaotalk.e2e.test.ts +7 -7
- package/e2e/line.e2e.test.ts +8 -8
- package/e2e/slack.e2e.test.ts +34 -34
- package/e2e/slackbot.e2e.test.ts +14 -14
- package/e2e/teams.e2e.test.ts +23 -23
- package/e2e/telegram.e2e.test.ts +8 -8
- package/e2e/webex.e2e.test.ts +14 -14
- package/e2e/whatsapp.e2e.test.ts +8 -8
- package/e2e/whatsappbot.e2e.test.ts +6 -6
- 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 +1 -1
- package/skills/agent-instagram/SKILL.md +1 -1
- package/skills/agent-kakaotalk/SKILL.md +1 -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-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/channeltalk/client.test.ts +26 -26
- package/src/platforms/channeltalk/commands/auth.test.ts +16 -16
- package/src/platforms/channeltalk/commands/bot.test.ts +2 -2
- package/src/platforms/channeltalk/commands/chat.test.ts +3 -3
- package/src/platforms/channeltalk/commands/group.test.ts +4 -4
- package/src/platforms/channeltalk/commands/manager.test.ts +2 -2
- package/src/platforms/channeltalk/commands/message.test.ts +17 -17
- package/src/platforms/channeltalk/commands/snapshot.test.ts +7 -7
- package/src/platforms/channeltalk/commands/whoami.test.ts +3 -3
- package/src/platforms/channeltalk/credential-manager.test.ts +18 -18
- package/src/platforms/channeltalk/ensure-auth.test.ts +5 -5
- package/src/platforms/channeltalk/index.test.ts +23 -23
- package/src/platforms/channeltalk/token-extractor.test.ts +21 -21
- package/src/platforms/channeltalk/types.test.ts +12 -12
- package/src/platforms/channeltalkbot/client.test.ts +14 -14
- package/src/platforms/channeltalkbot/commands/auth.test.ts +16 -16
- package/src/platforms/channeltalkbot/commands/bot.test.ts +6 -6
- package/src/platforms/channeltalkbot/commands/chat.test.ts +9 -9
- package/src/platforms/channeltalkbot/commands/group.test.ts +6 -6
- package/src/platforms/channeltalkbot/commands/manager.test.ts +3 -3
- package/src/platforms/channeltalkbot/commands/message.test.ts +10 -10
- package/src/platforms/channeltalkbot/commands/snapshot.test.ts +7 -7
- package/src/platforms/channeltalkbot/commands/whoami.test.ts +4 -4
- package/src/platforms/channeltalkbot/credential-manager.test.ts +27 -27
- package/src/platforms/channeltalkbot/index.test.ts +15 -15
- package/src/platforms/discord/client.test.ts +28 -28
- package/src/platforms/discord/commands/auth.test.ts +7 -7
- package/src/platforms/discord/commands/channel.test.ts +7 -7
- package/src/platforms/discord/commands/dm.test.ts +4 -4
- package/src/platforms/discord/commands/file.test.ts +4 -4
- package/src/platforms/discord/commands/friend.test.ts +6 -6
- package/src/platforms/discord/commands/member.test.ts +5 -5
- package/src/platforms/discord/commands/mention.test.ts +5 -5
- package/src/platforms/discord/commands/message.test.ts +9 -9
- package/src/platforms/discord/commands/note.test.ts +6 -6
- package/src/platforms/discord/commands/profile.test.ts +4 -4
- package/src/platforms/discord/commands/reaction.test.ts +5 -5
- package/src/platforms/discord/commands/server.test.ts +7 -7
- package/src/platforms/discord/commands/snapshot.test.ts +6 -6
- package/src/platforms/discord/commands/thread.test.ts +6 -6
- package/src/platforms/discord/commands/user.test.ts +5 -5
- package/src/platforms/discord/commands/whoami.test.ts +6 -6
- package/src/platforms/discord/credential-manager.test.ts +16 -16
- package/src/platforms/discord/ensure-auth.test.ts +8 -8
- package/src/platforms/discord/index.test.ts +17 -17
- package/src/platforms/discord/listener.test.ts +33 -33
- package/src/platforms/discord/token-extractor.test.ts +53 -53
- package/src/platforms/discord/types.test.ts +26 -26
- package/src/platforms/discordbot/client.test.ts +31 -31
- package/src/platforms/discordbot/commands/auth.test.ts +18 -18
- package/src/platforms/discordbot/commands/channel.test.ts +11 -11
- package/src/platforms/discordbot/commands/file.test.ts +7 -7
- package/src/platforms/discordbot/commands/message.test.ts +25 -25
- package/src/platforms/discordbot/commands/reaction.test.ts +6 -6
- package/src/platforms/discordbot/commands/server.test.ts +12 -12
- package/src/platforms/discordbot/commands/snapshot.test.ts +13 -13
- package/src/platforms/discordbot/commands/thread.test.ts +10 -10
- package/src/platforms/discordbot/commands/user.test.ts +9 -9
- package/src/platforms/discordbot/commands/whoami.test.ts +4 -4
- package/src/platforms/discordbot/credential-manager.test.ts +28 -28
- package/src/platforms/instagram/client.test.ts +18 -18
- package/src/platforms/instagram/commands/auth.test.ts +11 -11
- package/src/platforms/instagram/commands/chat.test.ts +6 -6
- package/src/platforms/instagram/commands/message.test.ts +11 -11
- package/src/platforms/instagram/commands/shared.test.ts +12 -12
- package/src/platforms/instagram/commands/whoami.test.ts +3 -3
- package/src/platforms/instagram/credential-manager.test.ts +21 -21
- package/src/platforms/instagram/ensure-auth.test.ts +4 -4
- package/src/platforms/instagram/index.test.ts +9 -9
- package/src/platforms/instagram/listener.test.ts +8 -8
- package/src/platforms/instagram/token-extractor.test.ts +35 -35
- package/src/platforms/kakaotalk/client.test.ts +33 -33
- package/src/platforms/kakaotalk/commands/auth.test.ts +11 -11
- package/src/platforms/kakaotalk/commands/chat.test.ts +6 -6
- package/src/platforms/kakaotalk/commands/message.test.ts +7 -7
- package/src/platforms/kakaotalk/commands/whoami.test.ts +5 -5
- package/src/platforms/kakaotalk/credential-manager.test.ts +15 -15
- package/src/platforms/kakaotalk/index.test.ts +15 -15
- package/src/platforms/kakaotalk/listener.test.ts +17 -17
- package/src/platforms/line/client.test.ts +17 -17
- package/src/platforms/line/commands/auth.test.ts +8 -8
- package/src/platforms/line/commands/chat.test.ts +7 -7
- package/src/platforms/line/commands/friend.test.ts +6 -6
- package/src/platforms/line/commands/message.test.ts +7 -7
- package/src/platforms/line/commands/whoami.test.ts +6 -6
- package/src/platforms/line/credential-manager.test.ts +17 -17
- package/src/platforms/line/index.test.ts +10 -10
- package/src/platforms/line/listener.test.ts +15 -15
- package/src/platforms/line/types.test.ts +14 -14
- package/src/platforms/slack/cli.test.ts +8 -8
- package/src/platforms/slack/client.test.ts +151 -151
- package/src/platforms/slack/commands/activity.test.ts +13 -13
- package/src/platforms/slack/commands/auth.test.ts +34 -34
- package/src/platforms/slack/commands/bookmark.test.ts +9 -9
- package/src/platforms/slack/commands/channel.test.ts +17 -17
- package/src/platforms/slack/commands/drafts.test.ts +7 -7
- package/src/platforms/slack/commands/emoji.test.ts +3 -3
- package/src/platforms/slack/commands/file.test.ts +12 -12
- package/src/platforms/slack/commands/message.test.ts +19 -19
- package/src/platforms/slack/commands/pin.test.ts +7 -7
- package/src/platforms/slack/commands/reaction.test.ts +10 -10
- package/src/platforms/slack/commands/reminder.test.ts +9 -9
- package/src/platforms/slack/commands/saved.test.ts +7 -7
- package/src/platforms/slack/commands/sections.test.ts +5 -5
- package/src/platforms/slack/commands/snapshot.test.ts +13 -13
- package/src/platforms/slack/commands/unread.test.ts +6 -6
- package/src/platforms/slack/commands/user.test.ts +10 -10
- package/src/platforms/slack/commands/usergroup.test.ts +15 -15
- package/src/platforms/slack/commands/whoami.test.ts +6 -6
- package/src/platforms/slack/commands/workspace.test.ts +26 -26
- package/src/platforms/slack/credential-manager.test.ts +14 -14
- package/src/platforms/slack/ensure-auth.test.ts +21 -21
- package/src/platforms/slack/index.test.ts +12 -12
- package/src/platforms/slack/listener.test.ts +17 -17
- package/src/platforms/slack/token-extractor-node.test.ts +2 -2
- package/src/platforms/slack/token-extractor.test.ts +37 -37
- package/src/platforms/slack/types.test.ts +21 -21
- package/src/platforms/slackbot/client.test.ts +22 -22
- package/src/platforms/slackbot/commands/auth.test.ts +14 -14
- package/src/platforms/slackbot/commands/channel.test.ts +7 -7
- package/src/platforms/slackbot/commands/message.test.ts +13 -13
- package/src/platforms/slackbot/commands/reaction.test.ts +6 -6
- package/src/platforms/slackbot/commands/user.test.ts +7 -7
- package/src/platforms/slackbot/commands/whoami.test.ts +4 -4
- package/src/platforms/slackbot/credential-manager.test.ts +22 -22
- package/src/platforms/slackbot/types.test.ts +7 -7
- package/src/platforms/teams/client.test.ts +30 -30
- package/src/platforms/teams/commands/auth.test.ts +8 -8
- package/src/platforms/teams/commands/channel.test.ts +7 -7
- package/src/platforms/teams/commands/file.test.ts +4 -4
- package/src/platforms/teams/commands/message.test.ts +5 -5
- package/src/platforms/teams/commands/reaction.test.ts +4 -4
- package/src/platforms/teams/commands/snapshot.test.ts +7 -7
- package/src/platforms/teams/commands/team.test.ts +8 -8
- package/src/platforms/teams/commands/user.test.ts +4 -4
- package/src/platforms/teams/commands/whoami.test.ts +6 -6
- package/src/platforms/teams/credential-manager.test.ts +17 -17
- package/src/platforms/teams/ensure-auth.test.ts +13 -13
- package/src/platforms/teams/index.test.ts +15 -15
- package/src/platforms/teams/token-extractor.test.ts +109 -49
- package/src/platforms/teams/token-extractor.ts +7 -2
- package/src/platforms/teams/types.test.ts +26 -26
- package/src/platforms/telegram/app-config.test.ts +4 -4
- package/src/platforms/telegram/chat-utils.test.ts +12 -12
- package/src/platforms/telegram/client.test.ts +4 -4
- package/src/platforms/telegram/commands/auth.test.ts +16 -16
- package/src/platforms/telegram/commands/chat.test.ts +9 -9
- package/src/platforms/telegram/commands/message.test.ts +6 -6
- package/src/platforms/telegram/commands/shared.test.ts +3 -3
- package/src/platforms/telegram/commands/whoami.test.ts +3 -3
- package/src/platforms/telegram/credential-manager.test.ts +10 -10
- package/src/platforms/telegram/types.test.ts +6 -6
- package/src/platforms/webex/app-config.test.ts +8 -8
- package/src/platforms/webex/cli.test.ts +5 -5
- package/src/platforms/webex/client.test.ts +65 -65
- package/src/platforms/webex/commands/auth.test.ts +18 -18
- package/src/platforms/webex/commands/member.test.ts +5 -5
- package/src/platforms/webex/commands/message.test.ts +12 -12
- package/src/platforms/webex/commands/snapshot.test.ts +5 -5
- package/src/platforms/webex/commands/space.test.ts +10 -10
- package/src/platforms/webex/commands/whoami.test.ts +6 -6
- package/src/platforms/webex/credential-manager.test.ts +22 -22
- package/src/platforms/webex/encryption.test.ts +4 -4
- package/src/platforms/webex/ensure-auth.test.ts +5 -5
- package/src/platforms/webex/index.test.ts +5 -5
- package/src/platforms/webex/markdown-to-html.test.ts +33 -33
- package/src/platforms/webex/token-extractor.test.ts +23 -23
- package/src/platforms/webex/types.test.ts +27 -27
- package/src/platforms/wechatbot/client.test.ts +27 -27
- package/src/platforms/wechatbot/commands/auth.test.ts +15 -15
- package/src/platforms/wechatbot/commands/message.test.ts +8 -8
- package/src/platforms/wechatbot/commands/template.test.ts +9 -9
- package/src/platforms/wechatbot/commands/user.test.ts +7 -7
- package/src/platforms/wechatbot/commands/whoami.test.ts +5 -5
- package/src/platforms/wechatbot/credential-manager.test.ts +18 -18
- package/src/platforms/wechatbot/index.test.ts +10 -10
- package/src/platforms/wechatbot/types.test.ts +25 -25
- package/src/platforms/whatsapp/commands/auth.test.ts +13 -13
- package/src/platforms/whatsapp/commands/chat.test.ts +8 -8
- package/src/platforms/whatsapp/commands/message.test.ts +10 -10
- package/src/platforms/whatsapp/commands/whoami.test.ts +3 -3
- package/src/platforms/whatsapp/credential-manager.test.ts +23 -23
- package/src/platforms/whatsapp/ensure-auth.test.ts +4 -4
- package/src/platforms/whatsapp/index.test.ts +8 -8
- package/src/platforms/whatsapp/types.test.ts +42 -42
- package/src/platforms/whatsappbot/client.test.ts +27 -27
- package/src/platforms/whatsappbot/commands/auth.test.ts +14 -14
- package/src/platforms/whatsappbot/commands/message.test.ts +16 -16
- package/src/platforms/whatsappbot/commands/template.test.ts +9 -9
- package/src/platforms/whatsappbot/commands/whoami.test.ts +5 -5
- package/src/platforms/whatsappbot/credential-manager.test.ts +18 -18
- package/src/platforms/whatsappbot/index.test.ts +7 -7
- package/src/platforms/whatsappbot/types.test.ts +18 -18
- package/src/shared/chromium/browsers.test.ts +22 -22
- package/src/shared/chromium/cookie-reader.test.ts +13 -13
- package/src/shared/chromium/decryptor.test.ts +97 -32
- package/src/shared/chromium/decryptor.ts +27 -6
- package/src/shared/utils/concurrency.test.ts +6 -6
- package/src/shared/utils/derived-key-cache.test.ts +11 -11
- package/src/tui/utils.test.ts +31 -31
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterAll, beforeEach, describe, expect,
|
|
1
|
+
import { afterAll, beforeEach, describe, expect, it } from 'bun:test'
|
|
2
2
|
import { existsSync, rmSync } from 'node:fs'
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
|
|
@@ -19,7 +19,7 @@ describe('CredentialManager', () => {
|
|
|
19
19
|
rmSync(testConfigDir, { recursive: true, force: true })
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
it('load() returns empty config when no file exists', async () => {
|
|
23
23
|
// Given: No credentials file exists
|
|
24
24
|
// When: load() is called
|
|
25
25
|
const config = await manager.load()
|
|
@@ -31,7 +31,7 @@ describe('CredentialManager', () => {
|
|
|
31
31
|
})
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
it('save() and load() round-trip', async () => {
|
|
35
35
|
// Given: A config with workspace credentials
|
|
36
36
|
const testConfig: Config = {
|
|
37
37
|
current_workspace: 'workspace-1',
|
|
@@ -55,7 +55,7 @@ describe('CredentialManager', () => {
|
|
|
55
55
|
expect(loaded).toEqual(testConfig)
|
|
56
56
|
})
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
it('save() creates credentials file with 0600 permissions', async () => {
|
|
59
59
|
// Given: A config to save
|
|
60
60
|
const testConfig: Config = {
|
|
61
61
|
current_workspace: null,
|
|
@@ -76,7 +76,7 @@ describe('CredentialManager', () => {
|
|
|
76
76
|
expect(permissions).toBe(0o600)
|
|
77
77
|
})
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
it('setWorkspace() adds or updates workspace', async () => {
|
|
80
80
|
// Given: A credential manager with empty config
|
|
81
81
|
// When: setWorkspace() is called
|
|
82
82
|
const creds: WorkspaceCredentials = {
|
|
@@ -92,7 +92,7 @@ describe('CredentialManager', () => {
|
|
|
92
92
|
expect(loaded.workspaces['ws-123']).toEqual(creds)
|
|
93
93
|
})
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
it('getWorkspace() returns workspace by id', async () => {
|
|
96
96
|
// Given: A workspace is saved
|
|
97
97
|
const creds: WorkspaceCredentials = {
|
|
98
98
|
workspace_id: 'ws-456',
|
|
@@ -109,7 +109,7 @@ describe('CredentialManager', () => {
|
|
|
109
109
|
expect(retrieved).toEqual(creds)
|
|
110
110
|
})
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
it('getWorkspace() returns null for non-existent workspace', async () => {
|
|
113
113
|
// Given: No workspace with this id exists
|
|
114
114
|
// When: getWorkspace() is called
|
|
115
115
|
const retrieved = await manager.getWorkspace('non-existent')
|
|
@@ -118,7 +118,7 @@ describe('CredentialManager', () => {
|
|
|
118
118
|
expect(retrieved).toBeNull()
|
|
119
119
|
})
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
it('getWorkspace() returns current workspace when no id provided', async () => {
|
|
122
122
|
// Given: A current workspace is set
|
|
123
123
|
const creds: WorkspaceCredentials = {
|
|
124
124
|
workspace_id: 'ws-789',
|
|
@@ -136,7 +136,7 @@ describe('CredentialManager', () => {
|
|
|
136
136
|
expect(retrieved).toEqual(creds)
|
|
137
137
|
})
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
it('getWorkspace() returns null when no current workspace set', async () => {
|
|
140
140
|
// Given: No current workspace is set
|
|
141
141
|
// When: getWorkspace() is called without id
|
|
142
142
|
const retrieved = await manager.getWorkspace()
|
|
@@ -145,7 +145,7 @@ describe('CredentialManager', () => {
|
|
|
145
145
|
expect(retrieved).toBeNull()
|
|
146
146
|
})
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
it('removeWorkspace() deletes workspace', async () => {
|
|
149
149
|
// Given: A workspace is saved
|
|
150
150
|
const creds: WorkspaceCredentials = {
|
|
151
151
|
workspace_id: 'ws-delete',
|
|
@@ -163,7 +163,7 @@ describe('CredentialManager', () => {
|
|
|
163
163
|
expect(retrieved).toBeNull()
|
|
164
164
|
})
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
it('removeWorkspace() clears current workspace if it matches', async () => {
|
|
167
167
|
// Given: A workspace is set as current
|
|
168
168
|
const creds: WorkspaceCredentials = {
|
|
169
169
|
workspace_id: 'ws-current',
|
|
@@ -182,7 +182,7 @@ describe('CredentialManager', () => {
|
|
|
182
182
|
expect(config.current_workspace).toBeNull()
|
|
183
183
|
})
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
it('setCurrentWorkspace() sets current workspace', async () => {
|
|
186
186
|
// Given: A workspace exists
|
|
187
187
|
const creds: WorkspaceCredentials = {
|
|
188
188
|
workspace_id: 'ws-set-current',
|
|
@@ -200,7 +200,7 @@ describe('CredentialManager', () => {
|
|
|
200
200
|
expect(config.current_workspace).toBe('ws-set-current')
|
|
201
201
|
})
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
it('creates config directory if it does not exist', async () => {
|
|
204
204
|
// Given: Config directory does not exist
|
|
205
205
|
expect(existsSync(testConfigDir)).toBe(false)
|
|
206
206
|
|
|
@@ -215,7 +215,7 @@ describe('CredentialManager', () => {
|
|
|
215
215
|
expect(existsSync(testConfigDir)).toBe(true)
|
|
216
216
|
})
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
it('multiple workspaces can coexist', async () => {
|
|
219
219
|
// Given: Multiple workspaces are added
|
|
220
220
|
const creds1: WorkspaceCredentials = {
|
|
221
221
|
workspace_id: 'ws-1',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, spyOn,
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, spyOn, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { SlackClient } from './client'
|
|
4
4
|
import { CredentialManager } from './credential-manager'
|
|
@@ -63,7 +63,7 @@ afterEach(() => {
|
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
describe('ensureSlackAuth', () => {
|
|
66
|
-
|
|
66
|
+
it('skips extraction when stored credentials are valid', async () => {
|
|
67
67
|
// given
|
|
68
68
|
getWorkspaceSpy.mockResolvedValue({
|
|
69
69
|
workspace_id: 'T123',
|
|
@@ -80,7 +80,7 @@ describe('ensureSlackAuth', () => {
|
|
|
80
80
|
expect(extractSpy).not.toHaveBeenCalled()
|
|
81
81
|
})
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
it('refreshes cookie when stored credentials are stale', async () => {
|
|
84
84
|
// given
|
|
85
85
|
getWorkspaceSpy.mockResolvedValue({
|
|
86
86
|
workspace_id: 'T123',
|
|
@@ -110,7 +110,7 @@ describe('ensureSlackAuth', () => {
|
|
|
110
110
|
expect(setWorkspaceSpy).toHaveBeenCalledWith(expect.objectContaining({ cookie: 'xoxd-fresh-cookie' }))
|
|
111
111
|
})
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
it('falls through to full extraction when cookie refresh fails', async () => {
|
|
114
114
|
// given
|
|
115
115
|
getWorkspaceSpy.mockResolvedValue({
|
|
116
116
|
workspace_id: 'T123',
|
|
@@ -128,7 +128,7 @@ describe('ensureSlackAuth', () => {
|
|
|
128
128
|
expect(extractSpy).toHaveBeenCalled()
|
|
129
129
|
})
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
it('extracts and saves credentials when none exist', async () => {
|
|
132
132
|
// when
|
|
133
133
|
await ensureSlackAuth()
|
|
134
134
|
|
|
@@ -145,7 +145,7 @@ describe('ensureSlackAuth', () => {
|
|
|
145
145
|
)
|
|
146
146
|
})
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
it('sets first workspace as current when none set', async () => {
|
|
149
149
|
// when
|
|
150
150
|
await ensureSlackAuth()
|
|
151
151
|
|
|
@@ -153,7 +153,7 @@ describe('ensureSlackAuth', () => {
|
|
|
153
153
|
expect(setCurrentWorkspaceSpy).toHaveBeenCalledWith('T123')
|
|
154
154
|
})
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
it('does not override existing current workspace', async () => {
|
|
157
157
|
// given
|
|
158
158
|
loadSpy.mockResolvedValue({
|
|
159
159
|
current_workspace: 'T999',
|
|
@@ -167,7 +167,7 @@ describe('ensureSlackAuth', () => {
|
|
|
167
167
|
expect(setCurrentWorkspaceSpy).not.toHaveBeenCalled()
|
|
168
168
|
})
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
it('handles multiple workspaces', async () => {
|
|
171
171
|
// given
|
|
172
172
|
extractSpy.mockResolvedValue([
|
|
173
173
|
{ workspace_id: 'T1', workspace_name: 'ws1', token: 'xoxc-1', cookie: 'xoxd-1' },
|
|
@@ -191,7 +191,7 @@ describe('ensureSlackAuth', () => {
|
|
|
191
191
|
expect(setCurrentWorkspaceSpy).toHaveBeenCalledWith('T1')
|
|
192
192
|
})
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
it('skips invalid workspaces during validation', async () => {
|
|
195
195
|
// given
|
|
196
196
|
extractSpy.mockResolvedValue([
|
|
197
197
|
{ workspace_id: 'T-bad', workspace_name: 'bad', token: 'xoxc-bad', cookie: 'xoxd-bad' },
|
|
@@ -213,7 +213,7 @@ describe('ensureSlackAuth', () => {
|
|
|
213
213
|
expect(setCurrentWorkspaceSpy).toHaveBeenCalledWith('T-good')
|
|
214
214
|
})
|
|
215
215
|
|
|
216
|
-
|
|
216
|
+
it('silently handles extraction failure', async () => {
|
|
217
217
|
// given
|
|
218
218
|
extractSpy.mockRejectedValue(new Error('Slack directory not found'))
|
|
219
219
|
|
|
@@ -224,7 +224,7 @@ describe('ensureSlackAuth', () => {
|
|
|
224
224
|
expect(setWorkspaceSpy).not.toHaveBeenCalled()
|
|
225
225
|
})
|
|
226
226
|
|
|
227
|
-
|
|
227
|
+
it('propagates cookie lock error when Slack app is running', async () => {
|
|
228
228
|
// given
|
|
229
229
|
const error = new Error(
|
|
230
230
|
'Failed to read Slack cookies. The Slack app is currently running and locking the cookie database. ' +
|
|
@@ -237,7 +237,7 @@ describe('ensureSlackAuth', () => {
|
|
|
237
237
|
await expect(ensureSlackAuth()).rejects.toThrow('locking the cookie')
|
|
238
238
|
})
|
|
239
239
|
|
|
240
|
-
|
|
240
|
+
it('does not save when no workspaces extracted', async () => {
|
|
241
241
|
// given
|
|
242
242
|
extractSpy.mockResolvedValue([])
|
|
243
243
|
|
|
@@ -249,7 +249,7 @@ describe('ensureSlackAuth', () => {
|
|
|
249
249
|
expect(setCurrentWorkspaceSpy).not.toHaveBeenCalled()
|
|
250
250
|
})
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
it('refreshes token from web when local token is invalid', async () => {
|
|
253
253
|
// given — local token is stale, but cookie is valid and domain is known
|
|
254
254
|
extractSpy.mockResolvedValue([
|
|
255
255
|
{ workspace_id: 'T-stale', workspace_name: 'stale-ws', token: 'xoxc-stale', cookie: 'xoxd-valid' },
|
|
@@ -278,7 +278,7 @@ describe('ensureSlackAuth', () => {
|
|
|
278
278
|
)
|
|
279
279
|
})
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
it('skips web refresh when no domain is known for workspace', async () => {
|
|
282
282
|
// given — domain mapping is empty
|
|
283
283
|
extractSpy.mockResolvedValue([
|
|
284
284
|
{ workspace_id: 'T-stale', workspace_name: 'stale-ws', token: 'xoxc-stale', cookie: 'xoxd-valid' },
|
|
@@ -294,7 +294,7 @@ describe('ensureSlackAuth', () => {
|
|
|
294
294
|
expect(setWorkspaceSpy).not.toHaveBeenCalled()
|
|
295
295
|
})
|
|
296
296
|
|
|
297
|
-
|
|
297
|
+
it('skips web refresh when workspace has no cookie', async () => {
|
|
298
298
|
// given — cookie is empty
|
|
299
299
|
extractSpy.mockResolvedValue([
|
|
300
300
|
{ workspace_id: 'T-stale', workspace_name: 'stale-ws', token: 'xoxc-stale', cookie: '' },
|
|
@@ -310,7 +310,7 @@ describe('ensureSlackAuth', () => {
|
|
|
310
310
|
expect(setWorkspaceSpy).not.toHaveBeenCalled()
|
|
311
311
|
})
|
|
312
312
|
|
|
313
|
-
|
|
313
|
+
it('updates workspace_name from auth response', async () => {
|
|
314
314
|
// given
|
|
315
315
|
extractSpy.mockResolvedValue([
|
|
316
316
|
{ workspace_id: 'T1', workspace_name: 'old-name', token: 'xoxc-1', cookie: 'xoxd-1' },
|
|
@@ -329,7 +329,7 @@ describe('ensureSlackAuth', () => {
|
|
|
329
329
|
expect(setWorkspaceSpy).toHaveBeenCalledWith(expect.objectContaining({ workspace_name: 'New Team Name' }))
|
|
330
330
|
})
|
|
331
331
|
|
|
332
|
-
|
|
332
|
+
it('resolves unknown workspace_id from testAuth before saving', async () => {
|
|
333
333
|
// given — extractor returns unknown workspace_id
|
|
334
334
|
extractSpy.mockResolvedValue([
|
|
335
335
|
{ workspace_id: 'unknown', workspace_name: 'unknown', token: 'xoxc-1', cookie: 'xoxd-1' },
|
|
@@ -352,7 +352,7 @@ describe('ensureSlackAuth', () => {
|
|
|
352
352
|
})
|
|
353
353
|
|
|
354
354
|
describe('refreshTokenFromWeb', () => {
|
|
355
|
-
|
|
355
|
+
it('extracts token from ssb/redirect HTML response', async () => {
|
|
356
356
|
// given
|
|
357
357
|
fetchSpy.mockResolvedValue(
|
|
358
358
|
new Response(
|
|
@@ -372,7 +372,7 @@ describe('refreshTokenFromWeb', () => {
|
|
|
372
372
|
})
|
|
373
373
|
})
|
|
374
374
|
|
|
375
|
-
|
|
375
|
+
it('returns null when response has no token', async () => {
|
|
376
376
|
// given
|
|
377
377
|
fetchSpy.mockResolvedValue(new Response('<html>no token here</html>', { status: 200 }))
|
|
378
378
|
|
|
@@ -383,7 +383,7 @@ describe('refreshTokenFromWeb', () => {
|
|
|
383
383
|
expect(token).toBeNull()
|
|
384
384
|
})
|
|
385
385
|
|
|
386
|
-
|
|
386
|
+
it('returns null on HTTP error', async () => {
|
|
387
387
|
// given
|
|
388
388
|
fetchSpy.mockResolvedValue(new Response('', { status: 403 }))
|
|
389
389
|
|
|
@@ -394,7 +394,7 @@ describe('refreshTokenFromWeb', () => {
|
|
|
394
394
|
expect(token).toBeNull()
|
|
395
395
|
})
|
|
396
396
|
|
|
397
|
-
|
|
397
|
+
it('returns null on network error', async () => {
|
|
398
398
|
// given
|
|
399
399
|
fetchSpy.mockRejectedValue(new Error('network timeout'))
|
|
400
400
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { expect,
|
|
1
|
+
import { expect, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
CredentialManager,
|
|
@@ -14,46 +14,46 @@ import {
|
|
|
14
14
|
ConfigSchema,
|
|
15
15
|
} from '@/platforms/slack/index'
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
it('SlackClient is exported from barrel', () => {
|
|
18
18
|
expect(typeof SlackClient).toBe('function')
|
|
19
19
|
})
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
it('SlackError is exported from barrel', () => {
|
|
22
22
|
expect(typeof SlackError).toBe('function')
|
|
23
23
|
})
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
it('CredentialManager is exported from barrel', () => {
|
|
26
26
|
expect(typeof CredentialManager).toBe('function')
|
|
27
27
|
})
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
it('SlackCredentialManager is exported from barrel', () => {
|
|
30
30
|
expect(typeof SlackCredentialManager).toBe('function')
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
it('SlackChannelSchema is exported from barrel', () => {
|
|
34
34
|
expect(typeof SlackChannelSchema.parse).toBe('function')
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
it('SlackReactionSchema is exported from barrel', () => {
|
|
38
38
|
expect(typeof SlackReactionSchema.parse).toBe('function')
|
|
39
39
|
})
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
it('SlackFileSchema is exported from barrel', () => {
|
|
42
42
|
expect(typeof SlackFileSchema.parse).toBe('function')
|
|
43
43
|
})
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
it('SlackMessageSchema is exported from barrel', () => {
|
|
46
46
|
expect(typeof SlackMessageSchema.parse).toBe('function')
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
it('SlackUserSchema is exported from barrel', () => {
|
|
50
50
|
expect(typeof SlackUserSchema.parse).toBe('function')
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
it('WorkspaceCredentialsSchema is exported from barrel', () => {
|
|
54
54
|
expect(typeof WorkspaceCredentialsSchema.parse).toBe('function')
|
|
55
55
|
})
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
it('ConfigSchema is exported from barrel', () => {
|
|
58
58
|
expect(typeof ConfigSchema.parse).toBe('function')
|
|
59
59
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterEach, describe, expect, mock,
|
|
1
|
+
import { afterEach, describe, expect, mock, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { SlackListener } from '@/platforms/slack/listener'
|
|
4
4
|
import type { SlackRTMMessageEvent, SlackRTMReactionEvent } from '@/platforms/slack/types'
|
|
@@ -79,7 +79,7 @@ describe('SlackListener', () => {
|
|
|
79
79
|
})
|
|
80
80
|
|
|
81
81
|
describe('start', () => {
|
|
82
|
-
|
|
82
|
+
it('calls rtmConnect and opens WebSocket', async () => {
|
|
83
83
|
const client = createMockClient()
|
|
84
84
|
listener = new SlackListener(client)
|
|
85
85
|
|
|
@@ -89,7 +89,7 @@ describe('SlackListener', () => {
|
|
|
89
89
|
expect(client.rtmConnect).toHaveBeenCalledTimes(1)
|
|
90
90
|
})
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
it('is idempotent', async () => {
|
|
93
93
|
const client = createMockClient()
|
|
94
94
|
listener = new SlackListener(client)
|
|
95
95
|
|
|
@@ -101,7 +101,7 @@ describe('SlackListener', () => {
|
|
|
101
101
|
})
|
|
102
102
|
|
|
103
103
|
describe('connected event', () => {
|
|
104
|
-
|
|
104
|
+
it('emits connected with self/team on hello', async () => {
|
|
105
105
|
const client = createMockClient()
|
|
106
106
|
listener = new SlackListener(client)
|
|
107
107
|
|
|
@@ -119,7 +119,7 @@ describe('SlackListener', () => {
|
|
|
119
119
|
})
|
|
120
120
|
|
|
121
121
|
describe('message events', () => {
|
|
122
|
-
|
|
122
|
+
it('emits message events', async () => {
|
|
123
123
|
const client = createMockClient()
|
|
124
124
|
listener = new SlackListener(client)
|
|
125
125
|
|
|
@@ -145,7 +145,7 @@ describe('SlackListener', () => {
|
|
|
145
145
|
})
|
|
146
146
|
|
|
147
147
|
describe('reaction events', () => {
|
|
148
|
-
|
|
148
|
+
it('emits reaction_added events', async () => {
|
|
149
149
|
const client = createMockClient()
|
|
150
150
|
listener = new SlackListener(client)
|
|
151
151
|
|
|
@@ -168,7 +168,7 @@ describe('SlackListener', () => {
|
|
|
168
168
|
})
|
|
169
169
|
|
|
170
170
|
describe('slack_event catch-all', () => {
|
|
171
|
-
|
|
171
|
+
it('emits slack_event for every non-hello event', async () => {
|
|
172
172
|
const client = createMockClient()
|
|
173
173
|
listener = new SlackListener(client)
|
|
174
174
|
|
|
@@ -188,7 +188,7 @@ describe('SlackListener', () => {
|
|
|
188
188
|
})
|
|
189
189
|
|
|
190
190
|
describe('ping/pong', () => {
|
|
191
|
-
|
|
191
|
+
it('does not treat pong reply as an event', async () => {
|
|
192
192
|
const client = createMockClient()
|
|
193
193
|
listener = new SlackListener(client)
|
|
194
194
|
|
|
@@ -205,7 +205,7 @@ describe('SlackListener', () => {
|
|
|
205
205
|
})
|
|
206
206
|
|
|
207
207
|
describe('stop', () => {
|
|
208
|
-
|
|
208
|
+
it('closes WebSocket and prevents reconnection', async () => {
|
|
209
209
|
const client = createMockClient()
|
|
210
210
|
listener = new SlackListener(client)
|
|
211
211
|
|
|
@@ -220,7 +220,7 @@ describe('SlackListener', () => {
|
|
|
220
220
|
})
|
|
221
221
|
|
|
222
222
|
describe('reconnection', () => {
|
|
223
|
-
|
|
223
|
+
it('reconnects on WebSocket close when still running', async () => {
|
|
224
224
|
const client = createMockClient()
|
|
225
225
|
listener = new SlackListener(client)
|
|
226
226
|
|
|
@@ -237,7 +237,7 @@ describe('SlackListener', () => {
|
|
|
237
237
|
expect(client.rtmConnect.mock.calls.length).toBeGreaterThanOrEqual(2)
|
|
238
238
|
})
|
|
239
239
|
|
|
240
|
-
|
|
240
|
+
it('emits error and reconnects on rtmConnect failure', async () => {
|
|
241
241
|
let callCount = 0
|
|
242
242
|
const client = createMockClient({
|
|
243
243
|
rtmConnect: mock(() => {
|
|
@@ -268,7 +268,7 @@ describe('SlackListener', () => {
|
|
|
268
268
|
})
|
|
269
269
|
|
|
270
270
|
describe('on/off/once', () => {
|
|
271
|
-
|
|
271
|
+
it('off removes listener', async () => {
|
|
272
272
|
const client = createMockClient()
|
|
273
273
|
listener = new SlackListener(client)
|
|
274
274
|
|
|
@@ -287,7 +287,7 @@ describe('SlackListener', () => {
|
|
|
287
287
|
expect(messages[0].text).toBe('a')
|
|
288
288
|
})
|
|
289
289
|
|
|
290
|
-
|
|
290
|
+
it('once fires only once', async () => {
|
|
291
291
|
const client = createMockClient()
|
|
292
292
|
listener = new SlackListener(client)
|
|
293
293
|
|
|
@@ -305,7 +305,7 @@ describe('SlackListener', () => {
|
|
|
305
305
|
})
|
|
306
306
|
|
|
307
307
|
describe('goodbye / team_migration_started', () => {
|
|
308
|
-
|
|
308
|
+
it('goodbye triggers immediate reconnect without backoff', async () => {
|
|
309
309
|
const client = createMockClient()
|
|
310
310
|
listener = new SlackListener(client)
|
|
311
311
|
|
|
@@ -322,7 +322,7 @@ describe('SlackListener', () => {
|
|
|
322
322
|
expect((listener as any).reconnectAttempts).toBe(0)
|
|
323
323
|
})
|
|
324
324
|
|
|
325
|
-
|
|
325
|
+
it('team_migration_started triggers immediate reconnect', async () => {
|
|
326
326
|
const client = createMockClient()
|
|
327
327
|
listener = new SlackListener(client)
|
|
328
328
|
|
|
@@ -336,7 +336,7 @@ describe('SlackListener', () => {
|
|
|
336
336
|
expect((listener as any).reconnectAttempts).toBe(0)
|
|
337
337
|
})
|
|
338
338
|
|
|
339
|
-
|
|
339
|
+
it('goodbye and team_migration_started are not emitted as events', async () => {
|
|
340
340
|
const client = createMockClient()
|
|
341
341
|
listener = new SlackListener(client)
|
|
342
342
|
|
|
@@ -356,7 +356,7 @@ describe('SlackListener', () => {
|
|
|
356
356
|
})
|
|
357
357
|
|
|
358
358
|
describe('start after stop', () => {
|
|
359
|
-
|
|
359
|
+
it('resets reconnect attempts on fresh start', async () => {
|
|
360
360
|
const client = createMockClient()
|
|
361
361
|
listener = new SlackListener(client)
|
|
362
362
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { expect,
|
|
1
|
+
import { expect, it } from 'bun:test'
|
|
2
2
|
import { execSync } from 'node:child_process'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
it('TokenExtractor works in Node.js', () => {
|
|
5
5
|
const result = execSync('bun tsx src/platforms/slack/token-extractor-node-test.ts', {
|
|
6
6
|
cwd: process.cwd(),
|
|
7
7
|
encoding: 'utf-8',
|