@urugus/slack-cli 0.2.11 → 0.2.13
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/README.md +4 -0
- package/dist/commands/history-display.d.ts +5 -1
- package/dist/commands/history-display.d.ts.map +1 -1
- package/dist/commands/history-display.js +3 -3
- package/dist/commands/history-display.js.map +1 -1
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +28 -11
- package/dist/commands/history.js.map +1 -1
- package/dist/types/commands.d.ts +1 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/utils/slack-api-client.d.ts +1 -0
- package/dist/utils/slack-api-client.d.ts.map +1 -1
- package/dist/utils/slack-api-client.js +3 -0
- package/dist/utils/slack-api-client.js.map +1 -1
- package/dist/utils/slack-operations/message-operations.d.ts +1 -0
- package/dist/utils/slack-operations/message-operations.d.ts.map +1 -1
- package/dist/utils/slack-operations/message-operations.js +21 -0
- package/dist/utils/slack-operations/message-operations.js.map +1 -1
- package/package.json +5 -2
- package/.claude/settings.local.json +0 -75
- package/.github/dependabot.yml +0 -18
- package/.github/workflows/ci.yml +0 -70
- package/.github/workflows/pr-validation.yml +0 -41
- package/.prettierignore +0 -11
- package/.prettierrc +0 -10
- package/CHANGELOG.md +0 -61
- package/CLAUDE.md +0 -16
- package/eslint.config.js +0 -38
- package/src/commands/channels.ts +0 -50
- package/src/commands/config-subcommands.ts +0 -63
- package/src/commands/config.ts +0 -50
- package/src/commands/history-display.ts +0 -19
- package/src/commands/history-validators.ts +0 -46
- package/src/commands/history.ts +0 -61
- package/src/commands/scheduled.ts +0 -71
- package/src/commands/send.ts +0 -69
- package/src/commands/unread.ts +0 -122
- package/src/index.ts +0 -27
- package/src/types/commands.ts +0 -58
- package/src/types/config.ts +0 -20
- package/src/utils/channel-formatter.ts +0 -45
- package/src/utils/channel-resolver.ts +0 -82
- package/src/utils/client-factory.ts +0 -10
- package/src/utils/command-wrapper.ts +0 -27
- package/src/utils/config/config-file-manager.ts +0 -56
- package/src/utils/config/profile-manager.ts +0 -79
- package/src/utils/config/token-crypto-service.ts +0 -80
- package/src/utils/config-helper.ts +0 -21
- package/src/utils/constants.ts +0 -78
- package/src/utils/date-utils.ts +0 -8
- package/src/utils/error-utils.ts +0 -6
- package/src/utils/errors.ts +0 -33
- package/src/utils/format-utils.ts +0 -9
- package/src/utils/formatters/base-formatter.ts +0 -34
- package/src/utils/formatters/channel-formatters.ts +0 -71
- package/src/utils/formatters/channels-list-formatters.ts +0 -55
- package/src/utils/formatters/history-formatters.ts +0 -123
- package/src/utils/formatters/message-formatters.ts +0 -85
- package/src/utils/mention-utils.ts +0 -47
- package/src/utils/option-parsers.ts +0 -100
- package/src/utils/profile-config.ts +0 -161
- package/src/utils/schedule-utils.ts +0 -41
- package/src/utils/slack-api-client.ts +0 -135
- package/src/utils/slack-operations/base-client.ts +0 -30
- package/src/utils/slack-operations/channel-operations.ts +0 -161
- package/src/utils/slack-operations/index.ts +0 -3
- package/src/utils/slack-operations/message-operations.ts +0 -176
- package/src/utils/slack-patterns.ts +0 -9
- package/src/utils/token-utils.ts +0 -17
- package/src/utils/validators.ts +0 -263
- package/tests/commands/channels.test.ts +0 -250
- package/tests/commands/config.test.ts +0 -158
- package/tests/commands/history.test.ts +0 -403
- package/tests/commands/scheduled.test.ts +0 -131
- package/tests/commands/send.test.ts +0 -414
- package/tests/commands/unread.test.ts +0 -492
- package/tests/index.test.ts +0 -40
- package/tests/test-utils.ts +0 -28
- package/tests/utils/channel-resolver.test.ts +0 -161
- package/tests/utils/config/config-file-manager.test.ts +0 -118
- package/tests/utils/config/profile-manager.test.ts +0 -266
- package/tests/utils/config/token-crypto-service.test.ts +0 -98
- package/tests/utils/config.test.ts +0 -400
- package/tests/utils/date-utils.test.ts +0 -30
- package/tests/utils/error-utils.test.ts +0 -34
- package/tests/utils/format-utils.test.ts +0 -61
- package/tests/utils/mention-utils.test.ts +0 -100
- package/tests/utils/option-parsers.test.ts +0 -173
- package/tests/utils/profile-config.test.ts +0 -282
- package/tests/utils/schedule-utils.test.ts +0 -63
- package/tests/utils/slack-api-client.test.ts +0 -313
- package/tests/utils/slack-operations/channel-operations.test.ts +0 -248
- package/tests/utils/slack-operations/message-operations.test.ts +0 -163
- package/tests/utils/token-utils.test.ts +0 -33
- package/tests/utils/validators.test.ts +0 -307
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -27
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
-
import { setupHistoryCommand } from '../../src/commands/history';
|
|
3
|
-
import { SlackApiClient } from '../../src/utils/slack-api-client';
|
|
4
|
-
import { ProfileConfigManager } from '../../src/utils/profile-config';
|
|
5
|
-
import { setupMockConsole, createTestProgram, restoreMocks } from '../test-utils';
|
|
6
|
-
import { ERROR_MESSAGES } from '../../src/utils/constants';
|
|
7
|
-
|
|
8
|
-
vi.mock('../../src/utils/slack-api-client');
|
|
9
|
-
vi.mock('../../src/utils/profile-config');
|
|
10
|
-
|
|
11
|
-
describe('history command', () => {
|
|
12
|
-
let program: any;
|
|
13
|
-
let mockSlackClient: SlackApiClient;
|
|
14
|
-
let mockConfigManager: ProfileConfigManager;
|
|
15
|
-
let mockConsole: any;
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
vi.clearAllMocks();
|
|
19
|
-
|
|
20
|
-
mockConfigManager = new ProfileConfigManager();
|
|
21
|
-
vi.mocked(ProfileConfigManager).mockReturnValue(mockConfigManager);
|
|
22
|
-
|
|
23
|
-
mockSlackClient = new SlackApiClient('test-token');
|
|
24
|
-
vi.mocked(SlackApiClient).mockReturnValue(mockSlackClient);
|
|
25
|
-
|
|
26
|
-
mockConsole = setupMockConsole();
|
|
27
|
-
program = createTestProgram();
|
|
28
|
-
program.addCommand(setupHistoryCommand());
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
restoreMocks();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('basic functionality', () => {
|
|
36
|
-
it('should fetch channel history with default options', async () => {
|
|
37
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
38
|
-
token: 'test-token',
|
|
39
|
-
updatedAt: new Date().toISOString()
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const mockMessages = [
|
|
43
|
-
{
|
|
44
|
-
type: 'message',
|
|
45
|
-
text: 'Hello world',
|
|
46
|
-
user: 'U123456',
|
|
47
|
-
ts: '1609459200.000100',
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
type: 'message',
|
|
51
|
-
text: 'Another message',
|
|
52
|
-
user: 'U789012',
|
|
53
|
-
ts: '1609459300.000200',
|
|
54
|
-
},
|
|
55
|
-
];
|
|
56
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
57
|
-
messages: mockMessages,
|
|
58
|
-
users: new Map([
|
|
59
|
-
['U123456', 'john.doe'],
|
|
60
|
-
['U789012', 'jane.smith']
|
|
61
|
-
])
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general']);
|
|
65
|
-
|
|
66
|
-
expect(mockSlackClient.getHistory).toHaveBeenCalledWith('general', {
|
|
67
|
-
limit: 10,
|
|
68
|
-
});
|
|
69
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Message History for #general'));
|
|
70
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('john.doe'));
|
|
71
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Hello world'));
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('should fetch history with custom message count', async () => {
|
|
75
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
76
|
-
token: 'test-token',
|
|
77
|
-
updatedAt: new Date().toISOString()
|
|
78
|
-
});
|
|
79
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
80
|
-
messages: [],
|
|
81
|
-
users: new Map()
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general', '-n', '20']);
|
|
85
|
-
|
|
86
|
-
expect(mockSlackClient.getHistory).toHaveBeenCalledWith('general', {
|
|
87
|
-
limit: 20,
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should fetch history since specific date', async () => {
|
|
92
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
93
|
-
token: 'test-token',
|
|
94
|
-
updatedAt: new Date().toISOString()
|
|
95
|
-
});
|
|
96
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
97
|
-
messages: [],
|
|
98
|
-
users: new Map()
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
const testDate = '2024-01-01 00:00:00';
|
|
102
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general', '--since', testDate]);
|
|
103
|
-
|
|
104
|
-
// Calculate expected timestamp based on the actual date parsing behavior
|
|
105
|
-
const expectedTimestamp = Math.floor(Date.parse(testDate) / 1000).toString();
|
|
106
|
-
|
|
107
|
-
expect(mockSlackClient.getHistory).toHaveBeenCalledWith('general', {
|
|
108
|
-
limit: 10,
|
|
109
|
-
oldest: expectedTimestamp,
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('should use specific profile when provided', async () => {
|
|
114
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
115
|
-
token: 'work-token',
|
|
116
|
-
updatedAt: new Date().toISOString()
|
|
117
|
-
});
|
|
118
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
119
|
-
messages: [],
|
|
120
|
-
users: new Map()
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general', '--profile', 'work']);
|
|
124
|
-
|
|
125
|
-
expect(mockConfigManager.getConfig).toHaveBeenCalledWith('work');
|
|
126
|
-
expect(SlackApiClient).toHaveBeenCalledWith('work-token');
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
describe('error handling', () => {
|
|
131
|
-
it('should show error when no configuration exists', async () => {
|
|
132
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue(null);
|
|
133
|
-
|
|
134
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general']);
|
|
135
|
-
|
|
136
|
-
expect(mockConsole.errorSpy).toHaveBeenCalledWith(expect.stringContaining('Error:'), expect.any(String));
|
|
137
|
-
expect(mockConsole.exitSpy).toHaveBeenCalledWith(1);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('should show error when profile not found', async () => {
|
|
141
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue(null);
|
|
142
|
-
|
|
143
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general', '--profile', 'unknown']);
|
|
144
|
-
|
|
145
|
-
expect(mockConsole.errorSpy).toHaveBeenCalledWith(expect.stringContaining('Error:'), expect.any(String));
|
|
146
|
-
expect(mockConsole.exitSpy).toHaveBeenCalledWith(1);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('should show error for invalid date format', async () => {
|
|
150
|
-
const historyCommand = setupHistoryCommand();
|
|
151
|
-
historyCommand.exitOverride();
|
|
152
|
-
|
|
153
|
-
await expect(
|
|
154
|
-
historyCommand.parseAsync(['-c', 'general', '--since', 'invalid-date'], { from: 'user' })
|
|
155
|
-
).rejects.toThrow();
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should show error for invalid message count', async () => {
|
|
159
|
-
const historyCommand = setupHistoryCommand();
|
|
160
|
-
historyCommand.exitOverride();
|
|
161
|
-
|
|
162
|
-
await expect(
|
|
163
|
-
historyCommand.parseAsync(['-c', 'general', '-n', '-5'], { from: 'user' })
|
|
164
|
-
).rejects.toThrow();
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should handle Slack API errors', async () => {
|
|
168
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
169
|
-
token: 'test-token',
|
|
170
|
-
updatedAt: new Date().toISOString()
|
|
171
|
-
});
|
|
172
|
-
vi.mocked(mockSlackClient.getHistory).mockRejectedValue(new Error('channel_not_found'));
|
|
173
|
-
|
|
174
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'nonexistent']);
|
|
175
|
-
|
|
176
|
-
expect(mockConsole.errorSpy).toHaveBeenCalledWith(expect.stringContaining('Error:'), expect.any(String));
|
|
177
|
-
expect(mockConsole.exitSpy).toHaveBeenCalledWith(1);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('should show helpful error when channel not found', async () => {
|
|
181
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
182
|
-
token: 'test-token',
|
|
183
|
-
updatedAt: new Date().toISOString()
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// Mock getHistory to throw our new helpful error
|
|
187
|
-
vi.mocked(mockSlackClient.getHistory).mockRejectedValue(
|
|
188
|
-
new Error("Channel 'times_sakashi' not found. Make sure you are a member of this channel.")
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'times_sakashi']);
|
|
192
|
-
|
|
193
|
-
expect(mockSlackClient.getHistory).toHaveBeenCalledWith('times_sakashi', { limit: 10 });
|
|
194
|
-
expect(mockConsole.errorSpy).toHaveBeenCalledWith(
|
|
195
|
-
expect.stringContaining('Error:'),
|
|
196
|
-
expect.stringContaining('Make sure you are a member of this channel')
|
|
197
|
-
);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it('should find private channels with underscore in name', async () => {
|
|
201
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
202
|
-
token: 'test-token',
|
|
203
|
-
updatedAt: new Date().toISOString()
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
// Mock the getHistory method to simulate successful channel lookup
|
|
207
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
208
|
-
messages: [],
|
|
209
|
-
users: new Map()
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'times_sakashi']);
|
|
213
|
-
|
|
214
|
-
expect(mockSlackClient.getHistory).toHaveBeenCalledWith('times_sakashi', { limit: 10 });
|
|
215
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('No messages found'));
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
describe('output formatting', () => {
|
|
220
|
-
describe('format options', () => {
|
|
221
|
-
it('should display messages in JSON format when --format json is specified', async () => {
|
|
222
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
223
|
-
token: 'test-token',
|
|
224
|
-
updatedAt: new Date().toISOString()
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
const mockMessages = [
|
|
228
|
-
{
|
|
229
|
-
type: 'message',
|
|
230
|
-
text: 'Hello world',
|
|
231
|
-
user: 'U123456',
|
|
232
|
-
ts: '1609459200.000100',
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
type: 'message',
|
|
236
|
-
text: 'Another message',
|
|
237
|
-
user: 'U789012',
|
|
238
|
-
ts: '1609459300.000200',
|
|
239
|
-
},
|
|
240
|
-
];
|
|
241
|
-
|
|
242
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
243
|
-
messages: mockMessages,
|
|
244
|
-
users: new Map([
|
|
245
|
-
['U123456', 'john.doe'],
|
|
246
|
-
['U789012', 'jane.smith']
|
|
247
|
-
])
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general', '--format', 'json']);
|
|
251
|
-
|
|
252
|
-
const expectedOutput = {
|
|
253
|
-
channel: 'general',
|
|
254
|
-
messages: [
|
|
255
|
-
{
|
|
256
|
-
timestamp: '2021-01-01 00:01:40',
|
|
257
|
-
user: 'jane.smith',
|
|
258
|
-
text: 'Another message'
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
timestamp: '2021-01-01 00:00:00',
|
|
262
|
-
user: 'john.doe',
|
|
263
|
-
text: 'Hello world'
|
|
264
|
-
}
|
|
265
|
-
],
|
|
266
|
-
total: 2
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(JSON.stringify(expectedOutput, null, 2));
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it('should display messages in simple format when --format simple is specified', async () => {
|
|
273
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
274
|
-
token: 'test-token',
|
|
275
|
-
updatedAt: new Date().toISOString()
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
const mockMessages = [
|
|
279
|
-
{
|
|
280
|
-
type: 'message',
|
|
281
|
-
text: 'Hello world',
|
|
282
|
-
user: 'U123456',
|
|
283
|
-
ts: '1609459200.000100',
|
|
284
|
-
},
|
|
285
|
-
];
|
|
286
|
-
|
|
287
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
288
|
-
messages: mockMessages,
|
|
289
|
-
users: new Map([['U123456', 'john.doe']])
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general', '--format', 'simple']);
|
|
293
|
-
|
|
294
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith('[2021-01-01 00:00:00] john.doe: Hello world');
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
it('should display messages in table format by default', async () => {
|
|
298
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
299
|
-
token: 'test-token',
|
|
300
|
-
updatedAt: new Date().toISOString()
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
const mockMessages = [
|
|
304
|
-
{
|
|
305
|
-
type: 'message',
|
|
306
|
-
text: 'Hello world',
|
|
307
|
-
user: 'U123456',
|
|
308
|
-
ts: '1609459200.000100',
|
|
309
|
-
},
|
|
310
|
-
];
|
|
311
|
-
|
|
312
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
313
|
-
messages: mockMessages,
|
|
314
|
-
users: new Map([['U123456', 'john.doe']])
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general']);
|
|
318
|
-
|
|
319
|
-
// Should display in table format (current format)
|
|
320
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Message History for #general'));
|
|
321
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('john.doe'));
|
|
322
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Hello world'));
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
it('should handle invalid format option', async () => {
|
|
326
|
-
const historyCommand = setupHistoryCommand();
|
|
327
|
-
historyCommand.exitOverride();
|
|
328
|
-
|
|
329
|
-
await expect(
|
|
330
|
-
historyCommand.parseAsync(['-c', 'general', '--format', 'invalid'], { from: 'user' })
|
|
331
|
-
).rejects.toThrow();
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
it('should format messages with user names and timestamps', async () => {
|
|
336
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
337
|
-
token: 'test-token',
|
|
338
|
-
updatedAt: new Date().toISOString()
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
const mockMessages = [
|
|
342
|
-
{
|
|
343
|
-
type: 'message',
|
|
344
|
-
text: 'Hello world',
|
|
345
|
-
user: 'U123456',
|
|
346
|
-
ts: '1609459200.000100',
|
|
347
|
-
},
|
|
348
|
-
];
|
|
349
|
-
|
|
350
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
351
|
-
messages: mockMessages,
|
|
352
|
-
users: new Map([['U123456', 'john.doe']])
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general']);
|
|
356
|
-
|
|
357
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('john.doe'));
|
|
358
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Hello world'));
|
|
359
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('✓ Displayed 1 message(s)'));
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
it('should handle messages without user info gracefully', async () => {
|
|
363
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
364
|
-
token: 'test-token',
|
|
365
|
-
updatedAt: new Date().toISOString()
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
const mockMessages = [
|
|
369
|
-
{
|
|
370
|
-
type: 'message',
|
|
371
|
-
text: 'Bot message',
|
|
372
|
-
bot_id: 'B123456',
|
|
373
|
-
ts: '1609459200.000100',
|
|
374
|
-
},
|
|
375
|
-
];
|
|
376
|
-
|
|
377
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
378
|
-
messages: mockMessages,
|
|
379
|
-
users: new Map()
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general']);
|
|
383
|
-
|
|
384
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Bot'));
|
|
385
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Bot message'));
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
it('should show message when no messages found', async () => {
|
|
389
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
390
|
-
token: 'test-token',
|
|
391
|
-
updatedAt: new Date().toISOString()
|
|
392
|
-
});
|
|
393
|
-
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
394
|
-
messages: [],
|
|
395
|
-
users: new Map()
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general']);
|
|
399
|
-
|
|
400
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('No messages found'));
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
});
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
-
import { setupScheduledCommand } from '../../src/commands/scheduled';
|
|
3
|
-
import { SlackApiClient } from '../../src/utils/slack-api-client';
|
|
4
|
-
import { ProfileConfigManager } from '../../src/utils/profile-config';
|
|
5
|
-
import { setupMockConsole, createTestProgram, restoreMocks } from '../test-utils';
|
|
6
|
-
|
|
7
|
-
vi.mock('../../src/utils/slack-api-client');
|
|
8
|
-
vi.mock('../../src/utils/profile-config');
|
|
9
|
-
|
|
10
|
-
describe('scheduled command', () => {
|
|
11
|
-
let program: any;
|
|
12
|
-
let mockSlackClient: SlackApiClient;
|
|
13
|
-
let mockConfigManager: ProfileConfigManager;
|
|
14
|
-
let mockConsole: any;
|
|
15
|
-
let tableSpy: any;
|
|
16
|
-
|
|
17
|
-
const mockScheduledMessages = [
|
|
18
|
-
{
|
|
19
|
-
id: 'Q123',
|
|
20
|
-
channel_id: 'C1234567890',
|
|
21
|
-
post_at: 1770855000,
|
|
22
|
-
date_created: 1770854400,
|
|
23
|
-
text: 'Scheduled message 1',
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
id: 'Q456',
|
|
27
|
-
channel_id: 'C0987654321',
|
|
28
|
-
post_at: 1770858600,
|
|
29
|
-
date_created: 1770854400,
|
|
30
|
-
text: 'Scheduled message 2',
|
|
31
|
-
},
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
beforeEach(() => {
|
|
35
|
-
vi.clearAllMocks();
|
|
36
|
-
|
|
37
|
-
mockConfigManager = new ProfileConfigManager();
|
|
38
|
-
vi.mocked(ProfileConfigManager).mockReturnValue(mockConfigManager);
|
|
39
|
-
|
|
40
|
-
mockSlackClient = new SlackApiClient('test-token');
|
|
41
|
-
vi.mocked(SlackApiClient).mockReturnValue(mockSlackClient);
|
|
42
|
-
|
|
43
|
-
mockConsole = setupMockConsole();
|
|
44
|
-
tableSpy = vi.spyOn(console, 'table').mockImplementation(() => {});
|
|
45
|
-
|
|
46
|
-
program = createTestProgram();
|
|
47
|
-
program.addCommand(setupScheduledCommand());
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
afterEach(() => {
|
|
51
|
-
restoreMocks();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should list scheduled messages in table format by default', async () => {
|
|
55
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
56
|
-
token: 'test-token',
|
|
57
|
-
updatedAt: new Date().toISOString(),
|
|
58
|
-
});
|
|
59
|
-
vi.mocked(mockSlackClient.listScheduledMessages).mockResolvedValue(
|
|
60
|
-
mockScheduledMessages as any
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
await program.parseAsync(['node', 'slack-cli', 'scheduled']);
|
|
64
|
-
|
|
65
|
-
expect(mockSlackClient.listScheduledMessages).toHaveBeenCalledWith(undefined, 50);
|
|
66
|
-
expect(tableSpy).toHaveBeenCalled();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('should filter by channel and limit', async () => {
|
|
70
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
71
|
-
token: 'test-token',
|
|
72
|
-
updatedAt: new Date().toISOString(),
|
|
73
|
-
});
|
|
74
|
-
vi.mocked(mockSlackClient.listScheduledMessages).mockResolvedValue(
|
|
75
|
-
mockScheduledMessages as any
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
await program.parseAsync([
|
|
79
|
-
'node',
|
|
80
|
-
'slack-cli',
|
|
81
|
-
'scheduled',
|
|
82
|
-
'--channel',
|
|
83
|
-
'general',
|
|
84
|
-
'--limit',
|
|
85
|
-
'10',
|
|
86
|
-
]);
|
|
87
|
-
|
|
88
|
-
expect(mockSlackClient.listScheduledMessages).toHaveBeenCalledWith('general', 10);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should output json format', async () => {
|
|
92
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
93
|
-
token: 'test-token',
|
|
94
|
-
updatedAt: new Date().toISOString(),
|
|
95
|
-
});
|
|
96
|
-
vi.mocked(mockSlackClient.listScheduledMessages).mockResolvedValue(
|
|
97
|
-
mockScheduledMessages as any
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
await program.parseAsync(['node', 'slack-cli', 'scheduled', '--format', 'json']);
|
|
101
|
-
|
|
102
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('"id": "Q123"'));
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should output simple format', async () => {
|
|
106
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
107
|
-
token: 'test-token',
|
|
108
|
-
updatedAt: new Date().toISOString(),
|
|
109
|
-
});
|
|
110
|
-
vi.mocked(mockSlackClient.listScheduledMessages).mockResolvedValue(
|
|
111
|
-
mockScheduledMessages as any
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
await program.parseAsync(['node', 'slack-cli', 'scheduled', '--format', 'simple']);
|
|
115
|
-
|
|
116
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Q123'));
|
|
117
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Q456'));
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should show empty message when no scheduled messages', async () => {
|
|
121
|
-
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
122
|
-
token: 'test-token',
|
|
123
|
-
updatedAt: new Date().toISOString(),
|
|
124
|
-
});
|
|
125
|
-
vi.mocked(mockSlackClient.listScheduledMessages).mockResolvedValue([] as any);
|
|
126
|
-
|
|
127
|
-
await program.parseAsync(['node', 'slack-cli', 'scheduled']);
|
|
128
|
-
|
|
129
|
-
expect(mockConsole.logSpy).toHaveBeenCalledWith('No scheduled messages found');
|
|
130
|
-
});
|
|
131
|
-
});
|