@urugus/slack-cli 0.2.3 → 0.2.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"format-utils.d.ts","sourceRoot":"","sources":["../../src/utils/format-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAM7F"}
1
+ {"version":3,"file":"format-utils.d.ts","sourceRoot":"","sources":["../../src/utils/format-utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAM7F"}
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.formatMessageWithMentions = formatMessageWithMentions;
4
+ const slack_patterns_1 = require("./slack-patterns");
4
5
  function formatMessageWithMentions(message, users) {
5
6
  // Replace <@USERID> mentions with @username
6
- return message.replace(/<@([A-Z0-9]+)>/g, (match, userId) => {
7
+ return message.replace(slack_patterns_1.USER_MENTION_PATTERN, (match, userId) => {
7
8
  const username = users.get(userId) || userId;
8
9
  return `@${username}`;
9
10
  });
@@ -1 +1 @@
1
- {"version":3,"file":"format-utils.js","sourceRoot":"","sources":["../../src/utils/format-utils.ts"],"names":[],"mappings":";;AAAA,8DAMC;AAND,SAAgB,yBAAyB,CAAC,OAAe,EAAE,KAA0B;IACnF,4CAA4C;IAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC1D,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;QAC7C,OAAO,IAAI,QAAQ,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"format-utils.js","sourceRoot":"","sources":["../../src/utils/format-utils.ts"],"names":[],"mappings":";;AAEA,8DAMC;AARD,qDAAwD;AAExD,SAAgB,yBAAyB,CAAC,OAAe,EAAE,KAA0B;IACnF,4CAA4C;IAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,qCAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;QAC7C,OAAO,IAAI,QAAQ,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Extracts all user IDs from mentions in a text
3
+ * @param text - The text containing Slack mentions
4
+ * @returns Array of unique user IDs found in mentions
5
+ */
6
+ export declare function extractUserIdsFromMentions(text: string): string[];
7
+ /**
8
+ * Extracts all unique user IDs from an array of messages
9
+ * Includes both message authors and mentioned users
10
+ * @param messages - Array of messages to extract user IDs from
11
+ * @returns Array of unique user IDs
12
+ */
13
+ export declare function extractAllUserIds(messages: Array<{
14
+ user?: string;
15
+ text?: string;
16
+ }>): string[];
17
+ //# sourceMappingURL=mention-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mention-utils.d.ts","sourceRoot":"","sources":["../../src/utils/mention-utils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAYjE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,EAAE,CAmB7F"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractUserIdsFromMentions = extractUserIdsFromMentions;
4
+ exports.extractAllUserIds = extractAllUserIds;
5
+ const slack_patterns_1 = require("./slack-patterns");
6
+ /**
7
+ * Extracts all user IDs from mentions in a text
8
+ * @param text - The text containing Slack mentions
9
+ * @returns Array of unique user IDs found in mentions
10
+ */
11
+ function extractUserIdsFromMentions(text) {
12
+ const userIds = [];
13
+ const matches = text.matchAll(slack_patterns_1.USER_MENTION_PATTERN);
14
+ for (const match of matches) {
15
+ const userId = match[1];
16
+ if (userId) {
17
+ userIds.push(userId);
18
+ }
19
+ }
20
+ return userIds;
21
+ }
22
+ /**
23
+ * Extracts all unique user IDs from an array of messages
24
+ * Includes both message authors and mentioned users
25
+ * @param messages - Array of messages to extract user IDs from
26
+ * @returns Array of unique user IDs
27
+ */
28
+ function extractAllUserIds(messages) {
29
+ const userIds = new Set();
30
+ for (const message of messages) {
31
+ // Add message author
32
+ if (message.user) {
33
+ userIds.add(message.user);
34
+ }
35
+ // Add mentioned users
36
+ if (message.text) {
37
+ const mentionedIds = extractUserIdsFromMentions(message.text);
38
+ for (const id of mentionedIds) {
39
+ userIds.add(id);
40
+ }
41
+ }
42
+ }
43
+ return Array.from(userIds);
44
+ }
45
+ //# sourceMappingURL=mention-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mention-utils.js","sourceRoot":"","sources":["../../src/utils/mention-utils.ts"],"names":[],"mappings":";;AAOA,gEAYC;AAQD,8CAmBC;AA9CD,qDAAwD;AAExD;;;;GAIG;AACH,SAAgB,0BAA0B,CAAC,IAAY;IACrD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,qCAAoB,CAAC,CAAC;IAEpD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,QAAiD;IACjF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,qBAAqB;QACrB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,sBAAsB;QACtB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,YAAY,GAAG,0BAA0B,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC9D,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"message-operations.d.ts","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAW,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGlG,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,UAAU,CAAoB;gBAE1B,KAAK,EAAE,MAAM;IAKnB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAO5E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAyB5E,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAsC/D,aAAa;CAmB5B"}
1
+ {"version":3,"file":"message-operations.d.ts","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAW,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAIlG,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,UAAU,CAAoB;gBAE1B,KAAK,EAAE,MAAM;IAKnB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAO5E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAyB5E,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAsC/D,aAAa;CAmB5B"}
@@ -5,6 +5,7 @@ const base_client_1 = require("./base-client");
5
5
  const channel_resolver_1 = require("../channel-resolver");
6
6
  const constants_1 = require("../constants");
7
7
  const channel_operations_1 = require("./channel-operations");
8
+ const mention_utils_1 = require("../mention-utils");
8
9
  class MessageOperations extends base_client_1.BaseSlackClient {
9
10
  constructor(token) {
10
11
  super(token);
@@ -29,8 +30,8 @@ class MessageOperations extends base_client_1.BaseSlackClient {
29
30
  oldest: options.oldest,
30
31
  });
31
32
  const messages = response.messages;
32
- // Get unique user IDs
33
- const userIds = [...new Set(messages.filter((m) => m.user).map((m) => m.user))];
33
+ // Extract all unique user IDs (authors and mentioned users)
34
+ const userIds = (0, mention_utils_1.extractAllUserIds)(messages);
34
35
  const users = await this.fetchUserInfo(userIds);
35
36
  return { messages, users };
36
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message-operations.js","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-operations.js","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Common regex patterns for Slack message parsing
3
+ */
4
+ export declare const USER_MENTION_PATTERN: RegExp;
5
+ export declare const SINGLE_USER_MENTION_PATTERN: RegExp;
6
+ //# sourceMappingURL=slack-patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-patterns.d.ts","sourceRoot":"","sources":["../../src/utils/slack-patterns.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,oBAAoB,QAAoB,CAAC;AAGtD,eAAO,MAAM,2BAA2B,QAAmB,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ /**
3
+ * Common regex patterns for Slack message parsing
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SINGLE_USER_MENTION_PATTERN = exports.USER_MENTION_PATTERN = void 0;
7
+ // Matches Slack user mentions in the format <@USERID>
8
+ exports.USER_MENTION_PATTERN = /<@([A-Z0-9]+)>/g;
9
+ // Matches a single user mention (non-global)
10
+ exports.SINGLE_USER_MENTION_PATTERN = /<@([A-Z0-9]+)>/;
11
+ //# sourceMappingURL=slack-patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-patterns.js","sourceRoot":"","sources":["../../src/utils/slack-patterns.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,sDAAsD;AACzC,QAAA,oBAAoB,GAAG,iBAAiB,CAAC;AAEtD,6CAA6C;AAChC,QAAA,2BAA2B,GAAG,gBAAgB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@urugus/slack-cli",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "A command-line tool for sending messages to Slack",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -1,6 +1,8 @@
1
+ import { USER_MENTION_PATTERN } from './slack-patterns';
2
+
1
3
  export function formatMessageWithMentions(message: string, users: Map<string, string>): string {
2
4
  // Replace <@USERID> mentions with @username
3
- return message.replace(/<@([A-Z0-9]+)>/g, (match, userId) => {
5
+ return message.replace(USER_MENTION_PATTERN, (match, userId) => {
4
6
  const username = users.get(userId) || userId;
5
7
  return `@${username}`;
6
8
  });
@@ -0,0 +1,47 @@
1
+ import { USER_MENTION_PATTERN } from './slack-patterns';
2
+
3
+ /**
4
+ * Extracts all user IDs from mentions in a text
5
+ * @param text - The text containing Slack mentions
6
+ * @returns Array of unique user IDs found in mentions
7
+ */
8
+ export function extractUserIdsFromMentions(text: string): string[] {
9
+ const userIds: string[] = [];
10
+ const matches = text.matchAll(USER_MENTION_PATTERN);
11
+
12
+ for (const match of matches) {
13
+ const userId = match[1];
14
+ if (userId) {
15
+ userIds.push(userId);
16
+ }
17
+ }
18
+
19
+ return userIds;
20
+ }
21
+
22
+ /**
23
+ * Extracts all unique user IDs from an array of messages
24
+ * Includes both message authors and mentioned users
25
+ * @param messages - Array of messages to extract user IDs from
26
+ * @returns Array of unique user IDs
27
+ */
28
+ export function extractAllUserIds(messages: Array<{ user?: string; text?: string }>): string[] {
29
+ const userIds = new Set<string>();
30
+
31
+ for (const message of messages) {
32
+ // Add message author
33
+ if (message.user) {
34
+ userIds.add(message.user);
35
+ }
36
+
37
+ // Add mentioned users
38
+ if (message.text) {
39
+ const mentionedIds = extractUserIdsFromMentions(message.text);
40
+ for (const id of mentionedIds) {
41
+ userIds.add(id);
42
+ }
43
+ }
44
+ }
45
+
46
+ return Array.from(userIds);
47
+ }
@@ -4,6 +4,7 @@ import { channelResolver } from '../channel-resolver';
4
4
  import { DEFAULTS } from '../constants';
5
5
  import { Message, HistoryOptions, HistoryResult, ChannelUnreadResult } from '../slack-api-client';
6
6
  import { ChannelOperations } from './channel-operations';
7
+ import { extractAllUserIds } from '../mention-utils';
7
8
 
8
9
  export class MessageOperations extends BaseSlackClient {
9
10
  private channelOps: ChannelOperations;
@@ -38,8 +39,8 @@ export class MessageOperations extends BaseSlackClient {
38
39
 
39
40
  const messages = response.messages as Message[];
40
41
 
41
- // Get unique user IDs
42
- const userIds = [...new Set(messages.filter((m) => m.user).map((m) => m.user!))];
42
+ // Extract all unique user IDs (authors and mentioned users)
43
+ const userIds = extractAllUserIds(messages);
43
44
  const users = await this.fetchUserInfo(userIds);
44
45
 
45
46
  return { messages, users };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Common regex patterns for Slack message parsing
3
+ */
4
+
5
+ // Matches Slack user mentions in the format <@USERID>
6
+ export const USER_MENTION_PATTERN = /<@([A-Z0-9]+)>/g;
7
+
8
+ // Matches a single user mention (non-global)
9
+ export const SINGLE_USER_MENTION_PATTERN = /<@([A-Z0-9]+)>/;
@@ -0,0 +1,100 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { extractUserIdsFromMentions, extractAllUserIds } from '../../src/utils/mention-utils';
3
+
4
+ describe('mention-utils', () => {
5
+ describe('extractUserIdsFromMentions', () => {
6
+ it('should extract single user ID from mention', () => {
7
+ const text = 'Hello <@U123456789>';
8
+ const userIds = extractUserIdsFromMentions(text);
9
+ expect(userIds).toEqual(['U123456789']);
10
+ });
11
+
12
+ it('should extract multiple user IDs from mentions', () => {
13
+ const text = 'Hey <@U123456789> and <@U987654321>, please check this';
14
+ const userIds = extractUserIdsFromMentions(text);
15
+ expect(userIds).toEqual(['U123456789', 'U987654321']);
16
+ });
17
+
18
+ it('should handle duplicate mentions', () => {
19
+ const text = '<@U123456789> mentioned <@U123456789> again';
20
+ const userIds = extractUserIdsFromMentions(text);
21
+ expect(userIds).toEqual(['U123456789', 'U123456789']);
22
+ });
23
+
24
+ it('should return empty array for text without mentions', () => {
25
+ const text = 'No mentions here';
26
+ const userIds = extractUserIdsFromMentions(text);
27
+ expect(userIds).toEqual([]);
28
+ });
29
+
30
+ it('should handle empty text', () => {
31
+ const userIds = extractUserIdsFromMentions('');
32
+ expect(userIds).toEqual([]);
33
+ });
34
+
35
+ it('should ignore malformed mentions', () => {
36
+ const text = 'Invalid <@> mention and <@lowercase> mention';
37
+ const userIds = extractUserIdsFromMentions(text);
38
+ expect(userIds).toEqual([]);
39
+ });
40
+ });
41
+
42
+ describe('extractAllUserIds', () => {
43
+ it('should extract user IDs from message authors only', () => {
44
+ const messages = [
45
+ { user: 'U111111111', text: 'Hello world' },
46
+ { user: 'U222222222', text: 'Hi there' },
47
+ ];
48
+ const userIds = extractAllUserIds(messages);
49
+ expect(userIds).toEqual(['U111111111', 'U222222222']);
50
+ });
51
+
52
+ it('should extract user IDs from mentions only', () => {
53
+ const messages = [
54
+ { text: 'Hello <@U333333333>' },
55
+ { text: 'Hi <@U444444444>' },
56
+ ];
57
+ const userIds = extractAllUserIds(messages);
58
+ expect(userIds).toEqual(['U333333333', 'U444444444']);
59
+ });
60
+
61
+ it('should extract both authors and mentioned users', () => {
62
+ const messages = [
63
+ { user: 'U111111111', text: 'Hello <@U222222222>' },
64
+ { user: 'U333333333', text: 'Hi <@U444444444> and <@U555555555>' },
65
+ ];
66
+ const userIds = extractAllUserIds(messages);
67
+ expect(userIds.sort()).toEqual([
68
+ 'U111111111',
69
+ 'U222222222',
70
+ 'U333333333',
71
+ 'U444444444',
72
+ 'U555555555',
73
+ ]);
74
+ });
75
+
76
+ it('should remove duplicate user IDs', () => {
77
+ const messages = [
78
+ { user: 'U111111111', text: 'Hello <@U111111111>' },
79
+ { user: 'U111111111', text: 'Another message' },
80
+ ];
81
+ const userIds = extractAllUserIds(messages);
82
+ expect(userIds).toEqual(['U111111111']);
83
+ });
84
+
85
+ it('should handle messages without user or text', () => {
86
+ const messages = [
87
+ { user: 'U111111111' },
88
+ { text: 'No user here' },
89
+ {},
90
+ ];
91
+ const userIds = extractAllUserIds(messages);
92
+ expect(userIds).toEqual(['U111111111']);
93
+ });
94
+
95
+ it('should handle empty messages array', () => {
96
+ const userIds = extractAllUserIds([]);
97
+ expect(userIds).toEqual([]);
98
+ });
99
+ });
100
+ });
@@ -0,0 +1,126 @@
1
+ import { beforeEach, describe, it, expect, vi } from 'vitest';
2
+ import { MessageOperations } from '../../../src/utils/slack-operations/message-operations';
3
+ import { channelResolver } from '../../../src/utils/channel-resolver';
4
+
5
+ vi.mock('@slack/web-api', () => ({
6
+ WebClient: vi.fn().mockImplementation(() => ({
7
+ conversations: {
8
+ history: vi.fn(),
9
+ },
10
+ users: {
11
+ info: vi.fn(),
12
+ },
13
+ chat: {
14
+ postMessage: vi.fn(),
15
+ },
16
+ })),
17
+ LogLevel: {
18
+ ERROR: 'error',
19
+ },
20
+ }));
21
+
22
+ vi.mock('../../../src/utils/channel-resolver');
23
+
24
+ describe('MessageOperations', () => {
25
+ let messageOps: MessageOperations;
26
+ let mockClient: any;
27
+
28
+ beforeEach(() => {
29
+ vi.clearAllMocks();
30
+ messageOps = new MessageOperations('test-token');
31
+ mockClient = (messageOps as any).client;
32
+ });
33
+
34
+ describe('getHistory with mentions', () => {
35
+ it('should fetch user info for mentioned users in message text', async () => {
36
+ const mockMessages = [
37
+ {
38
+ type: 'message',
39
+ text: 'Hello <@U123456789> can you check this?',
40
+ user: 'U987654321',
41
+ ts: '1234567890.123456',
42
+ },
43
+ {
44
+ type: 'message',
45
+ text: '<@U111111111> and <@U222222222> please review',
46
+ user: 'U333333333',
47
+ ts: '1234567891.123456',
48
+ },
49
+ ];
50
+
51
+ const mockUsersInfo = {
52
+ U123456789: { ok: true, user: { name: 'john.doe' } },
53
+ U987654321: { ok: true, user: { name: 'jane.smith' } },
54
+ U111111111: { ok: true, user: { name: 'alice.brown' } },
55
+ U222222222: { ok: true, user: { name: 'bob.wilson' } },
56
+ U333333333: { ok: true, user: { name: 'charlie.davis' } },
57
+ };
58
+
59
+ mockClient.conversations.history.mockResolvedValue({
60
+ ok: true,
61
+ messages: mockMessages,
62
+ });
63
+
64
+ mockClient.users.info.mockImplementation(({ user }: { user: string }) => {
65
+ return Promise.resolve(mockUsersInfo[user] || { ok: false });
66
+ });
67
+
68
+ vi.mocked(channelResolver.resolveChannelId).mockResolvedValue('C123456789');
69
+
70
+ const result = await messageOps.getHistory('test-channel', { limit: 10 });
71
+
72
+ // Verify all user IDs were fetched (both message authors and mentioned users)
73
+ expect(mockClient.users.info).toHaveBeenCalledTimes(5);
74
+ expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U987654321' });
75
+ expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U333333333' });
76
+ expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U123456789' });
77
+ expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U111111111' });
78
+ expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U222222222' });
79
+
80
+ // Verify the returned users map contains all users
81
+ expect(result.users.get('U123456789')).toBe('john.doe');
82
+ expect(result.users.get('U987654321')).toBe('jane.smith');
83
+ expect(result.users.get('U111111111')).toBe('alice.brown');
84
+ expect(result.users.get('U222222222')).toBe('bob.wilson');
85
+ expect(result.users.get('U333333333')).toBe('charlie.davis');
86
+ });
87
+
88
+ it('should handle messages with own mentions correctly', async () => {
89
+ const mockMessages = [
90
+ {
91
+ type: 'message',
92
+ text: '<@U07L5D50RAL> please check this task',
93
+ user: 'U123456789',
94
+ ts: '1234567890.123456',
95
+ },
96
+ ];
97
+
98
+ const mockUsersInfo = {
99
+ U123456789: { ok: true, user: { name: 'john.doe' } },
100
+ U07L5D50RAL: { ok: true, user: { name: 'koguchi_s' } },
101
+ };
102
+
103
+ mockClient.conversations.history.mockResolvedValue({
104
+ ok: true,
105
+ messages: mockMessages,
106
+ });
107
+
108
+ mockClient.users.info.mockImplementation(({ user }: { user: string }) => {
109
+ return Promise.resolve(mockUsersInfo[user] || { ok: false });
110
+ });
111
+
112
+ vi.mocked(channelResolver.resolveChannelId).mockResolvedValue('C123456789');
113
+
114
+ const result = await messageOps.getHistory('test-channel', { limit: 10 });
115
+
116
+ // Verify both users were fetched
117
+ expect(mockClient.users.info).toHaveBeenCalledTimes(2);
118
+ expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U123456789' });
119
+ expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U07L5D50RAL' });
120
+
121
+ // Verify the returned users map contains both users
122
+ expect(result.users.get('U123456789')).toBe('john.doe');
123
+ expect(result.users.get('U07L5D50RAL')).toBe('koguchi_s');
124
+ });
125
+ });
126
+ });