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 { describe, expect, mock,
|
|
1
|
+
import { describe, expect, mock, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { Command } from 'commander'
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ import { activityCommand } from '@/platforms/slack/commands/activity'
|
|
|
6
6
|
|
|
7
7
|
describe('activity command', () => {
|
|
8
8
|
describe('list subcommand', () => {
|
|
9
|
-
|
|
9
|
+
it('returns activity items', async () => {
|
|
10
10
|
const mockActivityItems = [
|
|
11
11
|
{
|
|
12
12
|
id: 'act_1',
|
|
@@ -36,7 +36,7 @@ describe('activity command', () => {
|
|
|
36
36
|
expect(result[1].type).toBe('message_reaction')
|
|
37
37
|
})
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
it('respects limit option', async () => {
|
|
40
40
|
const mockActivityItems = [
|
|
41
41
|
{
|
|
42
42
|
id: 'act_1',
|
|
@@ -56,7 +56,7 @@ describe('activity command', () => {
|
|
|
56
56
|
expect(result).toHaveLength(1)
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
it('respects unread-only mode', async () => {
|
|
60
60
|
const mockActivityItems = [
|
|
61
61
|
{
|
|
62
62
|
id: 'act_1',
|
|
@@ -76,7 +76,7 @@ describe('activity command', () => {
|
|
|
76
76
|
expect(result).toHaveLength(1)
|
|
77
77
|
})
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
it('respects types filter', async () => {
|
|
80
80
|
const mockActivityItems = [
|
|
81
81
|
{
|
|
82
82
|
id: 'act_1',
|
|
@@ -96,7 +96,7 @@ describe('activity command', () => {
|
|
|
96
96
|
expect(result).toHaveLength(1)
|
|
97
97
|
})
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
it('handles empty activity feed', async () => {
|
|
100
100
|
const mockGetActivityFeed = mock(() => Promise.resolve([]))
|
|
101
101
|
const result = await mockGetActivityFeed()
|
|
102
102
|
|
|
@@ -105,36 +105,36 @@ describe('activity command', () => {
|
|
|
105
105
|
})
|
|
106
106
|
|
|
107
107
|
describe('command structure', () => {
|
|
108
|
-
|
|
108
|
+
it('activity command exists', () => {
|
|
109
109
|
expect(activityCommand).toBeInstanceOf(Command)
|
|
110
110
|
})
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
it('activity command has correct name', () => {
|
|
113
113
|
expect(activityCommand.name()).toBe('activity')
|
|
114
114
|
})
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
it('activity command has description', () => {
|
|
117
117
|
expect(activityCommand.description()).toBe('Activity feed commands')
|
|
118
118
|
})
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
it('list subcommand exists', () => {
|
|
121
121
|
const listCmd = activityCommand.commands.find((cmd) => cmd.name() === 'list')
|
|
122
122
|
expect(listCmd).toBeDefined()
|
|
123
123
|
})
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
it('list subcommand has --unread option', () => {
|
|
126
126
|
const listCmd = activityCommand.commands.find((cmd) => cmd.name() === 'list')
|
|
127
127
|
const unreadOption = listCmd?.options.find((opt) => opt.long === '--unread')
|
|
128
128
|
expect(unreadOption).toBeDefined()
|
|
129
129
|
})
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
it('list subcommand has --limit option', () => {
|
|
132
132
|
const listCmd = activityCommand.commands.find((cmd) => cmd.name() === 'list')
|
|
133
133
|
const limitOption = listCmd?.options.find((opt) => opt.long === '--limit')
|
|
134
134
|
expect(limitOption).toBeDefined()
|
|
135
135
|
})
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
it('list subcommand has --types option', () => {
|
|
138
138
|
const listCmd = activityCommand.commands.find((cmd) => cmd.name() === 'list')
|
|
139
139
|
const typesOption = listCmd?.options.find((opt) => opt.long === '--types')
|
|
140
140
|
expect(typesOption).toBeDefined()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterAll, beforeEach, describe, expect, mock,
|
|
1
|
+
import { afterAll, beforeEach, describe, expect, mock, it } from 'bun:test'
|
|
2
2
|
import { mkdirSync, rmSync } from 'node:fs'
|
|
3
3
|
import { homedir } from 'node:os'
|
|
4
4
|
import { join } from 'node:path'
|
|
@@ -27,7 +27,7 @@ describe('TokenExtractor', () => {
|
|
|
27
27
|
})
|
|
28
28
|
|
|
29
29
|
describe('getSlackDir', () => {
|
|
30
|
-
|
|
30
|
+
it('returns correct path for darwin', () => {
|
|
31
31
|
// Given: Platform is darwin
|
|
32
32
|
extractor = new TokenExtractor('darwin')
|
|
33
33
|
|
|
@@ -49,7 +49,7 @@ describe('TokenExtractor', () => {
|
|
|
49
49
|
expect([directPath, sandboxedPath]).toContain(dir)
|
|
50
50
|
})
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
it('returns correct path for linux', () => {
|
|
53
53
|
// Given: Platform is linux
|
|
54
54
|
extractor = new TokenExtractor('linux')
|
|
55
55
|
|
|
@@ -60,7 +60,7 @@ describe('TokenExtractor', () => {
|
|
|
60
60
|
expect(dir).toBe(join(homedir(), '.config', 'Slack'))
|
|
61
61
|
})
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
it('returns correct path for win32', () => {
|
|
64
64
|
// Given: Platform is win32
|
|
65
65
|
extractor = new TokenExtractor('win32')
|
|
66
66
|
|
|
@@ -71,7 +71,7 @@ describe('TokenExtractor', () => {
|
|
|
71
71
|
expect(dir).toContain('Slack')
|
|
72
72
|
})
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
it('throws error for unsupported platform', () => {
|
|
75
75
|
// Given: Platform is unsupported
|
|
76
76
|
// When/Then: Constructor should throw
|
|
77
77
|
expect(() => new TokenExtractor('freebsd' as NodeJS.Platform)).toThrow('Unsupported platform')
|
|
@@ -79,7 +79,7 @@ describe('TokenExtractor', () => {
|
|
|
79
79
|
})
|
|
80
80
|
|
|
81
81
|
describe('extract', () => {
|
|
82
|
-
|
|
82
|
+
it('returns empty array when Slack directory does not exist (falls back to browser)', async () => {
|
|
83
83
|
// given
|
|
84
84
|
const nonExistentPath = `/tmp/nonexistent-slack-${Date.now()}-${Math.random()}`
|
|
85
85
|
extractor = new TokenExtractor('darwin', nonExistentPath)
|
|
@@ -91,7 +91,7 @@ describe('TokenExtractor', () => {
|
|
|
91
91
|
expect(result).toEqual([])
|
|
92
92
|
})
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
it('returns empty array when no tokens found', async () => {
|
|
95
95
|
// Given: Slack directory exists but has no tokens
|
|
96
96
|
mkdirSync(join(testSlackDir, 'storage'), { recursive: true })
|
|
97
97
|
extractor = new TokenExtractor('darwin', testSlackDir)
|
|
@@ -105,7 +105,7 @@ describe('TokenExtractor', () => {
|
|
|
105
105
|
})
|
|
106
106
|
|
|
107
107
|
describe('extractTokensFromLevelDB', () => {
|
|
108
|
-
|
|
108
|
+
it('extracts xoxc tokens from LevelDB', async () => {
|
|
109
109
|
// Given: LevelDB with xoxc token data
|
|
110
110
|
// This test requires mocking LevelDB - we'll test the integration
|
|
111
111
|
extractor = new TokenExtractor('darwin', testSlackDir)
|
|
@@ -117,7 +117,7 @@ describe('TokenExtractor', () => {
|
|
|
117
117
|
})
|
|
118
118
|
|
|
119
119
|
describe('extractCookieFromSQLite', () => {
|
|
120
|
-
|
|
120
|
+
it('extracts xoxd cookie from SQLite', async () => {
|
|
121
121
|
// Given: SQLite Cookies database with d cookie
|
|
122
122
|
// This test requires mocking SQLite - we'll test the integration
|
|
123
123
|
extractor = new TokenExtractor('darwin', testSlackDir)
|
|
@@ -143,7 +143,7 @@ describe('Auth Commands Integration', () => {
|
|
|
143
143
|
})
|
|
144
144
|
|
|
145
145
|
describe('auth extract', () => {
|
|
146
|
-
|
|
146
|
+
it('stores extracted workspaces in credential manager', async () => {
|
|
147
147
|
// Given: Extracted workspaces
|
|
148
148
|
const workspaces: ExtractedWorkspace[] = [
|
|
149
149
|
{
|
|
@@ -174,7 +174,7 @@ describe('Auth Commands Integration', () => {
|
|
|
174
174
|
expect(config.workspaces.T456.token).toBe('xoxc-789-012')
|
|
175
175
|
})
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
it('sets first workspace as current if none exists', async () => {
|
|
178
178
|
// Given: No current workspace
|
|
179
179
|
const workspace: ExtractedWorkspace = {
|
|
180
180
|
workspace_id: 'T789',
|
|
@@ -198,7 +198,7 @@ describe('Auth Commands Integration', () => {
|
|
|
198
198
|
})
|
|
199
199
|
|
|
200
200
|
describe('auth logout', () => {
|
|
201
|
-
|
|
201
|
+
it('removes workspace by id', async () => {
|
|
202
202
|
// Given: A workspace exists
|
|
203
203
|
await credManager.setWorkspace({
|
|
204
204
|
workspace_id: 'T-logout',
|
|
@@ -215,7 +215,7 @@ describe('Auth Commands Integration', () => {
|
|
|
215
215
|
expect(ws).toBeNull()
|
|
216
216
|
})
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
it('removes current workspace and clears current', async () => {
|
|
219
219
|
// Given: Current workspace is set
|
|
220
220
|
await credManager.setWorkspace({
|
|
221
221
|
workspace_id: 'T-current',
|
|
@@ -233,7 +233,7 @@ describe('Auth Commands Integration', () => {
|
|
|
233
233
|
expect(config.current_workspace).toBeNull()
|
|
234
234
|
})
|
|
235
235
|
|
|
236
|
-
|
|
236
|
+
it('throws error when workspace not found', async () => {
|
|
237
237
|
// Given: Workspace does not exist
|
|
238
238
|
// When: Trying to get non-existent workspace
|
|
239
239
|
const ws = await credManager.getWorkspace('nonexistent')
|
|
@@ -244,7 +244,7 @@ describe('Auth Commands Integration', () => {
|
|
|
244
244
|
})
|
|
245
245
|
|
|
246
246
|
describe('auth status', () => {
|
|
247
|
-
|
|
247
|
+
it('returns current workspace info', async () => {
|
|
248
248
|
// Given: A current workspace is set
|
|
249
249
|
await credManager.setWorkspace({
|
|
250
250
|
workspace_id: 'T-status',
|
|
@@ -263,7 +263,7 @@ describe('Auth Commands Integration', () => {
|
|
|
263
263
|
expect(ws?.workspace_name).toBe('status-test')
|
|
264
264
|
})
|
|
265
265
|
|
|
266
|
-
|
|
266
|
+
it('returns null when no workspace configured', async () => {
|
|
267
267
|
// Given: No workspace configured
|
|
268
268
|
// When: Getting current workspace
|
|
269
269
|
const ws = await credManager.getWorkspace()
|
|
@@ -272,7 +272,7 @@ describe('Auth Commands Integration', () => {
|
|
|
272
272
|
expect(ws).toBeNull()
|
|
273
273
|
})
|
|
274
274
|
|
|
275
|
-
|
|
275
|
+
it('validates token with Slack API', async () => {
|
|
276
276
|
// Given: A workspace with valid credentials
|
|
277
277
|
// This would require mocking SlackClient.testAuth()
|
|
278
278
|
// We test the integration pattern here
|
|
@@ -299,7 +299,7 @@ describe('Auth Commands Integration', () => {
|
|
|
299
299
|
})
|
|
300
300
|
|
|
301
301
|
describe('Platform Detection', () => {
|
|
302
|
-
|
|
302
|
+
it('auto-detects current platform', () => {
|
|
303
303
|
// Given: Running on current platform
|
|
304
304
|
const platform = process.platform
|
|
305
305
|
|
|
@@ -312,7 +312,7 @@ describe('Platform Detection', () => {
|
|
|
312
312
|
})
|
|
313
313
|
|
|
314
314
|
describe('Output Formatting', () => {
|
|
315
|
-
|
|
315
|
+
it('formats extract output correctly', () => {
|
|
316
316
|
// Given: Extracted workspaces
|
|
317
317
|
const output = {
|
|
318
318
|
workspaces: ['T123/acme-corp', 'T456/side-project'],
|
|
@@ -328,7 +328,7 @@ describe('Output Formatting', () => {
|
|
|
328
328
|
expect(pretty).toContain('\n')
|
|
329
329
|
})
|
|
330
330
|
|
|
331
|
-
|
|
331
|
+
it('formats status output correctly', () => {
|
|
332
332
|
// Given: Status info
|
|
333
333
|
const output = {
|
|
334
334
|
workspace_id: 'T123',
|
|
@@ -345,7 +345,7 @@ describe('Output Formatting', () => {
|
|
|
345
345
|
expect(JSON.parse(json)).toEqual(output)
|
|
346
346
|
})
|
|
347
347
|
|
|
348
|
-
|
|
348
|
+
it('formats logout output correctly', () => {
|
|
349
349
|
// Given: Logout result
|
|
350
350
|
const output = {
|
|
351
351
|
removed: 'T123',
|
|
@@ -369,7 +369,7 @@ describe('formatCredentialDebug', () => {
|
|
|
369
369
|
cookie: 'xoxd-abc123def456ghi789jkl012mno345pqr678stu901vwx234yz',
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
|
|
372
|
+
it('truncates token and hides cookie by default', () => {
|
|
373
373
|
const result = formatCredentialDebug(ws)
|
|
374
374
|
|
|
375
375
|
expect(result).toContain('T123ABC')
|
|
@@ -379,7 +379,7 @@ describe('formatCredentialDebug', () => {
|
|
|
379
379
|
expect(result).not.toContain(ws.cookie)
|
|
380
380
|
})
|
|
381
381
|
|
|
382
|
-
|
|
382
|
+
it('shows full token and cookie when showSecrets is true', () => {
|
|
383
383
|
const result = formatCredentialDebug(ws, true)
|
|
384
384
|
|
|
385
385
|
expect(result).toContain(ws.token)
|
|
@@ -388,14 +388,14 @@ describe('formatCredentialDebug', () => {
|
|
|
388
388
|
expect(result).not.toContain('present')
|
|
389
389
|
})
|
|
390
390
|
|
|
391
|
-
|
|
391
|
+
it('shows cookie=missing when cookie is empty and secrets hidden', () => {
|
|
392
392
|
const wsNoCookie = { ...ws, cookie: '' }
|
|
393
393
|
const result = formatCredentialDebug(wsNoCookie)
|
|
394
394
|
|
|
395
395
|
expect(result).toContain('cookie=missing')
|
|
396
396
|
})
|
|
397
397
|
|
|
398
|
-
|
|
398
|
+
it('shows empty cookie value when cookie is empty and secrets shown', () => {
|
|
399
399
|
const wsNoCookie = { ...ws, cookie: '' }
|
|
400
400
|
const result = formatCredentialDebug(wsNoCookie, true)
|
|
401
401
|
|
|
@@ -405,35 +405,35 @@ describe('formatCredentialDebug', () => {
|
|
|
405
405
|
})
|
|
406
406
|
|
|
407
407
|
describe('getExtractionErrorMessage', () => {
|
|
408
|
-
|
|
408
|
+
it('returns cookie failure message for missing_cookie', () => {
|
|
409
409
|
const message = getExtractionErrorMessage(['missing_cookie'])
|
|
410
410
|
|
|
411
411
|
expect(message).toContain('Cookie extraction failed')
|
|
412
412
|
expect(message).toContain('desktop app or a supported Chromium browser')
|
|
413
413
|
})
|
|
414
414
|
|
|
415
|
-
|
|
415
|
+
it('returns session expired message for invalid_auth', () => {
|
|
416
416
|
const message = getExtractionErrorMessage(['invalid_auth'])
|
|
417
417
|
|
|
418
418
|
expect(message).toContain('session has expired')
|
|
419
419
|
expect(message).toContain('desktop app or a supported Chromium browser')
|
|
420
420
|
})
|
|
421
421
|
|
|
422
|
-
|
|
422
|
+
it('prioritizes missing_cookie over invalid_auth', () => {
|
|
423
423
|
const message = getExtractionErrorMessage(['invalid_auth', 'missing_cookie'])
|
|
424
424
|
|
|
425
425
|
expect(message).toContain('Cookie extraction failed')
|
|
426
426
|
expect(message).toContain('desktop app or a supported Chromium browser')
|
|
427
427
|
})
|
|
428
428
|
|
|
429
|
-
|
|
429
|
+
it('returns generic message for unknown error codes', () => {
|
|
430
430
|
const message = getExtractionErrorMessage(['unknown_error'])
|
|
431
431
|
|
|
432
432
|
expect(message).toContain('Extracted tokens are invalid')
|
|
433
433
|
expect(message).toContain('desktop app or a supported Chromium browser')
|
|
434
434
|
})
|
|
435
435
|
|
|
436
|
-
|
|
436
|
+
it('returns generic message for empty failure list', () => {
|
|
437
437
|
const message = getExtractionErrorMessage([])
|
|
438
438
|
|
|
439
439
|
expect(message).toContain('Extracted tokens are invalid')
|
|
@@ -442,7 +442,7 @@ describe('getExtractionErrorMessage', () => {
|
|
|
442
442
|
})
|
|
443
443
|
|
|
444
444
|
describe('getNoWorkspacesFoundMessage', () => {
|
|
445
|
-
|
|
445
|
+
it('mentions desktop app and browser fallback', () => {
|
|
446
446
|
expect(getNoWorkspacesFoundMessage()).toContain('desktop app or a supported Chromium browser')
|
|
447
447
|
})
|
|
448
448
|
})
|
|
@@ -457,7 +457,7 @@ describe('Error Handling', () => {
|
|
|
457
457
|
rmSync(testSlackDir, { recursive: true, force: true })
|
|
458
458
|
})
|
|
459
459
|
|
|
460
|
-
|
|
460
|
+
it('handles missing Slack installation gracefully', async () => {
|
|
461
461
|
// given — Slack is not installed
|
|
462
462
|
const nonExistentPath = `/tmp/nonexistent-slack-${Date.now()}-${Math.random()}`
|
|
463
463
|
const extractor = new TokenExtractor('darwin', nonExistentPath)
|
|
@@ -467,7 +467,7 @@ describe('Error Handling', () => {
|
|
|
467
467
|
expect(result).toEqual([])
|
|
468
468
|
})
|
|
469
469
|
|
|
470
|
-
|
|
470
|
+
it('handles empty Slack directory gracefully', async () => {
|
|
471
471
|
// Given: Slack directory exists but has no data
|
|
472
472
|
const extractor = new TokenExtractor('darwin', testSlackDir)
|
|
473
473
|
|
|
@@ -478,7 +478,7 @@ describe('Error Handling', () => {
|
|
|
478
478
|
expect(result).toEqual([])
|
|
479
479
|
})
|
|
480
480
|
|
|
481
|
-
|
|
481
|
+
it('handles missing Cookies database gracefully', async () => {
|
|
482
482
|
// Given: No Cookies database
|
|
483
483
|
mkdirSync(join(testSlackDir, 'storage'), { recursive: true })
|
|
484
484
|
const extractor = new TokenExtractor('darwin', testSlackDir)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, mock,
|
|
1
|
+
import { beforeEach, describe, expect, mock, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { SlackClient } from '@/platforms/slack/client'
|
|
4
4
|
import type { SlackBookmark } from '@/platforms/slack/types'
|
|
@@ -27,13 +27,13 @@ describe('Bookmark Commands', () => {
|
|
|
27
27
|
})
|
|
28
28
|
|
|
29
29
|
describe('bookmark add', () => {
|
|
30
|
-
|
|
30
|
+
it('adds a bookmark successfully', async () => {
|
|
31
31
|
const result = await (mockClient as SlackClient).addBookmark('C001', 'Test Bookmark', 'https://example.com')
|
|
32
32
|
expect(result.id).toBe('Bm001')
|
|
33
33
|
expect(result.title).toBe('Test Bookmark')
|
|
34
34
|
})
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
it('throws error when API fails', async () => {
|
|
37
37
|
mockClient.addBookmark = mock(async () => {
|
|
38
38
|
throw new Error('channel_not_found')
|
|
39
39
|
})
|
|
@@ -44,12 +44,12 @@ describe('Bookmark Commands', () => {
|
|
|
44
44
|
})
|
|
45
45
|
|
|
46
46
|
describe('bookmark edit', () => {
|
|
47
|
-
|
|
47
|
+
it('edits a bookmark successfully', async () => {
|
|
48
48
|
const result = await (mockClient as SlackClient).editBookmark('C001', 'Bm001', { title: 'Updated Title' })
|
|
49
49
|
expect(result.title).toBe('Updated Title')
|
|
50
50
|
})
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
it('throws error when API fails', async () => {
|
|
53
53
|
mockClient.editBookmark = mock(async () => {
|
|
54
54
|
throw new Error('bookmark_not_found')
|
|
55
55
|
})
|
|
@@ -60,12 +60,12 @@ describe('Bookmark Commands', () => {
|
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
describe('bookmark remove', () => {
|
|
63
|
-
|
|
63
|
+
it('removes a bookmark successfully', async () => {
|
|
64
64
|
await (mockClient as SlackClient).removeBookmark('C001', 'Bm001')
|
|
65
65
|
expect(mockClient.removeBookmark).toHaveBeenCalledWith('C001', 'Bm001')
|
|
66
66
|
})
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
it('throws error when API fails', async () => {
|
|
69
69
|
mockClient.removeBookmark = mock(async () => {
|
|
70
70
|
throw new Error('bookmark_not_found')
|
|
71
71
|
})
|
|
@@ -74,14 +74,14 @@ describe('Bookmark Commands', () => {
|
|
|
74
74
|
})
|
|
75
75
|
|
|
76
76
|
describe('bookmark list', () => {
|
|
77
|
-
|
|
77
|
+
it('lists bookmarks in a channel', async () => {
|
|
78
78
|
const bookmarks = await (mockClient as SlackClient).listBookmarks('C001')
|
|
79
79
|
expect(bookmarks).toHaveLength(1)
|
|
80
80
|
expect(bookmarks[0].title).toBe('Test Bookmark')
|
|
81
81
|
expect(bookmarks[0].link).toBe('https://example.com')
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
it('throws error when API fails', async () => {
|
|
85
85
|
mockClient.listBookmarks = mock(async () => {
|
|
86
86
|
throw new Error('channel_not_found')
|
|
87
87
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, mock,
|
|
1
|
+
import { beforeEach, describe, expect, mock, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { SlackClient } from '@/platforms/slack/client'
|
|
4
4
|
import type { SlackChannel, SlackUser } from '@/platforms/slack/types'
|
|
@@ -124,7 +124,7 @@ describe('Channel Commands', () => {
|
|
|
124
124
|
})
|
|
125
125
|
|
|
126
126
|
describe('channel list', () => {
|
|
127
|
-
|
|
127
|
+
it('lists all channels', async () => {
|
|
128
128
|
// Given: SlackClient returns channels
|
|
129
129
|
// When: Listing channels
|
|
130
130
|
const channels = await mockClient.listChannels()
|
|
@@ -136,7 +136,7 @@ describe('Channel Commands', () => {
|
|
|
136
136
|
expect(channels[2].name).toBe('archived-channel')
|
|
137
137
|
})
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
it('excludes archived channels by default', async () => {
|
|
140
140
|
// Given: SlackClient returns channels including archived
|
|
141
141
|
const channels = await mockClient.listChannels()
|
|
142
142
|
|
|
@@ -148,7 +148,7 @@ describe('Channel Commands', () => {
|
|
|
148
148
|
expect(activeChannels.every((c) => !c.is_archived)).toBe(true)
|
|
149
149
|
})
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
it('includes archived channels when requested', async () => {
|
|
152
152
|
// Given: SlackClient returns channels including archived
|
|
153
153
|
const channels = await mockClient.listChannels()
|
|
154
154
|
|
|
@@ -158,7 +158,7 @@ describe('Channel Commands', () => {
|
|
|
158
158
|
expect(channels.some((c) => c.is_archived)).toBe(true)
|
|
159
159
|
})
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
it('filters channels by type=public', async () => {
|
|
162
162
|
// Given: SlackClient returns mixed channels
|
|
163
163
|
// When: Filtering by public type
|
|
164
164
|
const channels = await mockClient.listChannels()
|
|
@@ -169,7 +169,7 @@ describe('Channel Commands', () => {
|
|
|
169
169
|
expect(publicChannels.every((c) => !c.is_private)).toBe(true)
|
|
170
170
|
})
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
it('filters channels by type=private', async () => {
|
|
173
173
|
// Given: SlackClient returns mixed channels
|
|
174
174
|
// When: Filtering by private type
|
|
175
175
|
const channels = await mockClient.listChannels()
|
|
@@ -182,7 +182,7 @@ describe('Channel Commands', () => {
|
|
|
182
182
|
})
|
|
183
183
|
|
|
184
184
|
describe('channel info', () => {
|
|
185
|
-
|
|
185
|
+
it('gets channel by ID', async () => {
|
|
186
186
|
// Given: Channel ID C001
|
|
187
187
|
// When: Getting channel info
|
|
188
188
|
const channel = await mockClient.getChannel('C001')
|
|
@@ -193,7 +193,7 @@ describe('Channel Commands', () => {
|
|
|
193
193
|
expect(channel.is_private).toBe(false)
|
|
194
194
|
})
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
it('throws error for non-existent channel', async () => {
|
|
197
197
|
// Given: Non-existent channel ID
|
|
198
198
|
// When: Getting channel info
|
|
199
199
|
// Then: Should throw error
|
|
@@ -205,7 +205,7 @@ describe('Channel Commands', () => {
|
|
|
205
205
|
}
|
|
206
206
|
})
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
it('returns channel with topic and purpose', async () => {
|
|
209
209
|
// Given: Channel with topic and purpose
|
|
210
210
|
// When: Getting channel info
|
|
211
211
|
const channel = await mockClient.getChannel('C001')
|
|
@@ -217,7 +217,7 @@ describe('Channel Commands', () => {
|
|
|
217
217
|
})
|
|
218
218
|
|
|
219
219
|
describe('channel history (alias for message list)', () => {
|
|
220
|
-
|
|
220
|
+
it('history command should be alias for message list', () => {
|
|
221
221
|
// Given: channel history command
|
|
222
222
|
// When: Checking command structure
|
|
223
223
|
// Then: Should be alias for message list
|
|
@@ -226,7 +226,7 @@ describe('Channel Commands', () => {
|
|
|
226
226
|
})
|
|
227
227
|
|
|
228
228
|
describe('channel open', () => {
|
|
229
|
-
|
|
229
|
+
it('opens a DM channel with a single user', async () => {
|
|
230
230
|
// Given: A user ID
|
|
231
231
|
// When: Opening a conversation
|
|
232
232
|
const result = await mockClient.openConversation('U001')
|
|
@@ -237,7 +237,7 @@ describe('Channel Commands', () => {
|
|
|
237
237
|
expect(mockClient.openConversation).toHaveBeenCalledWith('U001')
|
|
238
238
|
})
|
|
239
239
|
|
|
240
|
-
|
|
240
|
+
it('returns already_open when DM exists', async () => {
|
|
241
241
|
// Given: An existing DM conversation
|
|
242
242
|
;(mockClient.openConversation as any).mockImplementation(async () => ({
|
|
243
243
|
channel_id: 'D0ABC123',
|
|
@@ -252,7 +252,7 @@ describe('Channel Commands', () => {
|
|
|
252
252
|
expect(result.already_open).toBe(true)
|
|
253
253
|
})
|
|
254
254
|
|
|
255
|
-
|
|
255
|
+
it('opens a group DM with multiple users', async () => {
|
|
256
256
|
// Given: Multiple user IDs
|
|
257
257
|
;(mockClient.openConversation as any).mockImplementation(async () => ({
|
|
258
258
|
channel_id: 'G0ABC123',
|
|
@@ -269,7 +269,7 @@ describe('Channel Commands', () => {
|
|
|
269
269
|
})
|
|
270
270
|
|
|
271
271
|
describe('channel users', () => {
|
|
272
|
-
|
|
272
|
+
it('lists members of a channel via listChannelMembers and getUser', async () => {
|
|
273
273
|
// Given: Channel C001 with 3 members
|
|
274
274
|
const memberIds = await mockClient.listChannelMembers('C001')
|
|
275
275
|
|
|
@@ -285,7 +285,7 @@ describe('Channel Commands', () => {
|
|
|
285
285
|
expect(mockClient.getUser).toHaveBeenCalledTimes(3)
|
|
286
286
|
})
|
|
287
287
|
|
|
288
|
-
|
|
288
|
+
it('filters out bots by default', async () => {
|
|
289
289
|
// Given: Channel with human and bot members
|
|
290
290
|
const memberIds = await mockClient.listChannelMembers('C001')
|
|
291
291
|
const users = await Promise.all(memberIds.map((id) => mockClient.getUser(id)))
|
|
@@ -298,7 +298,7 @@ describe('Channel Commands', () => {
|
|
|
298
298
|
expect(filtered.every((u) => !u.is_bot)).toBe(true)
|
|
299
299
|
})
|
|
300
300
|
|
|
301
|
-
|
|
301
|
+
it('includes bots with --include-bots flag', async () => {
|
|
302
302
|
// Given: Channel with human and bot members
|
|
303
303
|
const memberIds = await mockClient.listChannelMembers('C001')
|
|
304
304
|
const users = await Promise.all(memberIds.map((id) => mockClient.getUser(id)))
|
|
@@ -309,7 +309,7 @@ describe('Channel Commands', () => {
|
|
|
309
309
|
expect(users.some((u) => u.is_bot)).toBe(true)
|
|
310
310
|
})
|
|
311
311
|
|
|
312
|
-
|
|
312
|
+
it('returns user profiles with expected output shape', async () => {
|
|
313
313
|
// Given: Channel member with profile
|
|
314
314
|
const user = await mockClient.getUser('U001')
|
|
315
315
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, mock,
|
|
1
|
+
import { beforeEach, describe, expect, mock, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { SlackClient } from '@/platforms/slack/client'
|
|
4
4
|
|
|
@@ -51,7 +51,7 @@ describe('Drafts Commands', () => {
|
|
|
51
51
|
})
|
|
52
52
|
|
|
53
53
|
describe('drafts list', () => {
|
|
54
|
-
|
|
54
|
+
it('returns drafts', async () => {
|
|
55
55
|
// Given: Client with drafts
|
|
56
56
|
// When: Getting drafts
|
|
57
57
|
const result = await mockClient.getDrafts()
|
|
@@ -62,7 +62,7 @@ describe('Drafts Commands', () => {
|
|
|
62
62
|
expect(result.drafts[0].message?.text).toBe('Draft message 1')
|
|
63
63
|
})
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
it('handles empty message content gracefully', async () => {
|
|
66
66
|
// Given: Client with drafts including null/empty message
|
|
67
67
|
// When: Getting drafts
|
|
68
68
|
const result = await mockClient.getDrafts()
|
|
@@ -74,7 +74,7 @@ describe('Drafts Commands', () => {
|
|
|
74
74
|
expect(result.drafts[3].message).toEqual({})
|
|
75
75
|
})
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
it('pagination with cursor works', async () => {
|
|
78
78
|
// Given: Client with pagination support
|
|
79
79
|
// When: Getting first page
|
|
80
80
|
const firstPage = await mockClient.getDrafts()
|
|
@@ -89,7 +89,7 @@ describe('Drafts Commands', () => {
|
|
|
89
89
|
expect(secondPage.next_cursor).toBeUndefined()
|
|
90
90
|
})
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
it('returns next_cursor for pagination', async () => {
|
|
93
93
|
// Given: Client with more drafts available
|
|
94
94
|
// When: Getting drafts
|
|
95
95
|
const result = await mockClient.getDrafts()
|
|
@@ -101,7 +101,7 @@ describe('Drafts Commands', () => {
|
|
|
101
101
|
})
|
|
102
102
|
|
|
103
103
|
describe('output formatting', () => {
|
|
104
|
-
|
|
104
|
+
it('formats draft output', async () => {
|
|
105
105
|
// Given: Drafts from API
|
|
106
106
|
const result = await mockClient.getDrafts()
|
|
107
107
|
|
|
@@ -119,7 +119,7 @@ describe('Drafts Commands', () => {
|
|
|
119
119
|
expect(output[0].text).toBe('Draft message 1')
|
|
120
120
|
})
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
it('handles null message in output', async () => {
|
|
123
123
|
// Given: Draft with null message
|
|
124
124
|
const result = await mockClient.getDrafts()
|
|
125
125
|
|