@hubspot/cli 7.10.0-beta.1 → 7.10.0-experimental.0
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/bin/cli.js +5 -4
- package/commands/__tests__/getStarted.test.js +10 -0
- package/commands/__tests__/project.test.js +3 -0
- package/commands/account/__tests__/rename.test.js +10 -3
- package/commands/account/auth.js +10 -14
- package/commands/account/clean.js +11 -19
- package/commands/account/createOverride.js +15 -11
- package/commands/account/info.js +8 -5
- package/commands/account/list.js +15 -19
- package/commands/account/remove.js +23 -22
- package/commands/account/removeOverride.js +6 -6
- package/commands/account/rename.js +2 -2
- package/commands/account/use.js +19 -8
- package/commands/app/__tests__/migrate.test.js +8 -4
- package/commands/app/migrate.js +2 -2
- package/commands/auth.js +18 -14
- package/commands/config/migrate.js +5 -5
- package/commands/customObject/createSchema.js +2 -3
- package/commands/customObject/updateSchema.js +2 -3
- package/commands/getStarted.js +2 -3
- package/commands/hubdb/__tests__/list.test.js +1 -0
- package/commands/hubdb/list.js +2 -2
- package/commands/init.js +36 -32
- package/commands/project/__tests__/deploy.test.js +10 -5
- package/commands/project/__tests__/devUnifiedFlow.test.js +6 -4
- package/commands/project/__tests__/lint.test.js +709 -0
- package/commands/project/__tests__/logs.test.js +4 -0
- package/commands/project/__tests__/validate.test.js +2 -2
- package/commands/project/cloneApp.js +2 -2
- package/commands/project/deploy.js +2 -2
- package/commands/project/dev/deprecatedFlow.js +4 -5
- package/commands/project/dev/index.js +6 -3
- package/commands/project/dev/unifiedFlow.js +4 -5
- package/commands/project/lint.d.ts +6 -0
- package/commands/project/lint.js +178 -0
- package/commands/project/logs.js +2 -3
- package/commands/project/profile/add.js +6 -7
- package/commands/project/profile/delete.js +2 -2
- package/commands/project/upload.js +2 -2
- package/commands/project/validate.js +2 -2
- package/commands/project.js +2 -0
- package/commands/sandbox/__tests__/create.test.js +14 -5
- package/commands/sandbox/create.js +4 -5
- package/commands/sandbox/delete.js +23 -20
- package/commands/testAccount/__tests__/create.test.js +5 -5
- package/commands/testAccount/create.js +2 -2
- package/commands/testAccount/delete.js +9 -8
- package/lang/en.d.ts +40 -6
- package/lang/en.js +54 -14
- package/lib/__tests__/buildAccount.test.js +22 -30
- package/lib/__tests__/commonOpts.test.js +9 -13
- package/lib/__tests__/developerTestAccounts.test.js +29 -17
- package/lib/__tests__/importData.test.js +20 -10
- package/lib/__tests__/oauth.test.js +19 -8
- package/lib/__tests__/sandboxSync.test.js +33 -11
- package/lib/__tests__/sandboxes.test.js +30 -19
- package/lib/__tests__/usageTracking.test.js +10 -10
- package/lib/__tests__/validation.test.js +32 -32
- package/lib/accountTypes.d.ts +9 -9
- package/lib/accountTypes.js +2 -4
- package/lib/app/__tests__/migrate.test.js +15 -0
- package/lib/app/__tests__/migrate_legacy.test.js +9 -0
- package/lib/app/migrate_legacy.d.ts +2 -2
- package/lib/buildAccount.d.ts +4 -4
- package/lib/buildAccount.js +7 -14
- package/lib/commonOpts.js +3 -3
- package/lib/configMigrate.d.ts +2 -2
- package/lib/configMigrate.js +42 -18
- package/lib/configOptions.js +3 -2
- package/lib/developerTestAccounts.d.ts +3 -3
- package/lib/developerTestAccounts.js +4 -7
- package/lib/doctor/DiagnosticInfoBuilder.d.ts +1 -1
- package/lib/doctor/DiagnosticInfoBuilder.js +9 -6
- package/lib/doctor/Doctor.js +4 -3
- package/lib/doctor/__tests__/Diagnosis.test.js +4 -3
- package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +17 -9
- package/lib/doctor/__tests__/Doctor.test.js +14 -0
- package/lib/importData.js +8 -7
- package/lib/links.js +5 -5
- package/lib/middleware/{__test__ → __tests__}/commandTargetingUtils.test.js +3 -3
- package/lib/middleware/{__test__ → __tests__}/configMiddleware.test.js +23 -22
- package/lib/middleware/{__test__ → __tests__}/gitMiddleware.test.js +9 -7
- package/lib/middleware/autoUpdateMiddleware.js +12 -4
- package/lib/middleware/commandTargetingUtils.js +3 -2
- package/lib/middleware/configMiddleware.d.ts +6 -1
- package/lib/middleware/configMiddleware.js +36 -15
- package/lib/middleware/gitMiddleware.js +8 -4
- package/lib/oauth.d.ts +2 -2
- package/lib/oauth.js +8 -10
- package/lib/projects/__tests__/AppDevModeInterface.test.js +17 -6
- package/lib/projects/__tests__/DevServerManager.test.js +1 -0
- package/lib/projects/__tests__/LocalDevProcess.test.js +1 -0
- package/lib/projects/__tests__/components.test.js +1 -1
- package/lib/projects/__tests__/deploy.test.js +1 -0
- package/lib/projects/__tests__/uieLinting.test.js +640 -0
- package/lib/projects/components.js +1 -1
- package/lib/projects/create/__tests__/v2.test.js +11 -0
- package/lib/projects/localDev/AppDevModeInterface.js +2 -2
- package/lib/projects/localDev/DevServerManager_DEPRECATED.js +2 -2
- package/lib/projects/localDev/DevSessionManager.d.ts +17 -0
- package/lib/projects/localDev/DevSessionManager.js +56 -0
- package/lib/projects/localDev/LocalDevLogger.d.ts +3 -0
- package/lib/projects/localDev/LocalDevLogger.js +13 -4
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +3 -3
- package/lib/projects/localDev/LocalDevProcess.d.ts +1 -0
- package/lib/projects/localDev/LocalDevProcess.js +12 -1
- package/lib/projects/localDev/LocalDevState.d.ts +3 -0
- package/lib/projects/localDev/LocalDevState.js +9 -0
- package/lib/projects/localDev/helpers/account.d.ts +10 -10
- package/lib/projects/localDev/helpers/account.js +6 -11
- package/lib/projects/localDev/helpers/devSessionsApi.d.ts +9 -0
- package/lib/projects/localDev/helpers/devSessionsApi.js +19 -0
- package/lib/projects/uieLinting.d.ts +33 -0
- package/lib/projects/uieLinting.js +222 -0
- package/lib/projects/urls.js +5 -6
- package/lib/prompts/__tests__/downloadProjectPrompt.test.js +7 -5
- package/lib/prompts/accountNamePrompt.js +3 -3
- package/lib/prompts/accountsPrompt.d.ts +1 -1
- package/lib/prompts/accountsPrompt.js +6 -7
- package/lib/prompts/confirmImportDataPrompt.js +2 -2
- package/lib/prompts/downloadProjectPrompt.d.ts +1 -0
- package/lib/prompts/downloadProjectPrompt.js +5 -2
- package/lib/prompts/importDataTestAccountSelectPrompt.js +4 -5
- package/lib/prompts/personalAccessKeyPrompt.js +2 -2
- package/lib/prompts/projectDevTargetAccountPrompt.d.ts +3 -3
- package/lib/prompts/projectDevTargetAccountPrompt.js +5 -7
- package/lib/prompts/sandboxesPrompt.js +7 -8
- package/lib/prompts/setAsDefaultAccountPrompt.js +7 -6
- package/lib/sandboxSync.d.ts +2 -2
- package/lib/sandboxSync.js +3 -9
- package/lib/sandboxes.d.ts +4 -4
- package/lib/sandboxes.js +6 -11
- package/lib/serverlessLogs.js +2 -2
- package/lib/theme/__tests__/migrate.test.js +15 -0
- package/lib/ui/index.js +6 -3
- package/lib/usageTracking.js +15 -8
- package/lib/validation.js +13 -11
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +4 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.js +4 -2
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +4 -2
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +4 -2
- package/mcp-server/tools/cms/HsListFunctionsTool.js +3 -1
- package/mcp-server/tools/cms/HsListTool.js +3 -1
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +1 -0
- package/mcp-server/tools/index.js +4 -0
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +4 -2
- package/mcp-server/tools/project/CreateProjectTool.js +4 -2
- package/mcp-server/tools/project/CreateTestAccountTool.js +42 -19
- package/mcp-server/tools/project/DeployProjectTool.js +3 -1
- package/mcp-server/tools/project/DocFetchTool.js +6 -4
- package/mcp-server/tools/project/DocsSearchTool.d.ts +1 -1
- package/mcp-server/tools/project/DocsSearchTool.js +10 -8
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +1 -1
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +9 -7
- package/mcp-server/tools/project/GetApplicationInfoTool.js +8 -6
- package/mcp-server/tools/project/GetBuildLogsTool.d.ts +26 -0
- package/mcp-server/tools/project/GetBuildLogsTool.js +125 -0
- package/mcp-server/tools/project/GetBuildStatusTool.d.ts +26 -0
- package/mcp-server/tools/project/GetBuildStatusTool.js +166 -0
- package/mcp-server/tools/project/GetConfigValuesTool.d.ts +1 -1
- package/mcp-server/tools/project/GetConfigValuesTool.js +9 -7
- package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +1 -1
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +5 -3
- package/mcp-server/tools/project/UploadProjectTools.js +3 -1
- package/mcp-server/tools/project/ValidateProjectTool.js +4 -2
- package/mcp-server/tools/project/__tests__/CreateTestAccountTool.test.js +226 -3
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +5 -1
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +23 -11
- package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +7 -5
- package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +7 -5
- package/mcp-server/tools/project/__tests__/GetBuildLogsTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GetBuildLogsTool.test.js +305 -0
- package/mcp-server/tools/project/__tests__/GetBuildStatusTool.test.d.ts +1 -0
- package/mcp-server/tools/project/__tests__/GetBuildStatusTool.test.js +240 -0
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +8 -6
- package/mcp-server/utils/__tests__/content.test.js +21 -20
- package/mcp-server/utils/__tests__/feedbackTracking.test.js +34 -28
- package/mcp-server/utils/config.d.ts +1 -0
- package/mcp-server/utils/config.js +10 -0
- package/mcp-server/utils/content.d.ts +1 -1
- package/mcp-server/utils/content.js +2 -2
- package/mcp-server/utils/feedbackTracking.d.ts +1 -1
- package/mcp-server/utils/feedbackTracking.js +3 -3
- package/mcp-server/utils/toolUsageTracking.js +4 -3
- package/package.json +8 -7
- package/types/LocalDev.d.ts +1 -0
- package/lib/middleware/__test__/notificationsMiddleware.test.js +0 -8
- package/lib/middleware/notificationsMiddleware.d.ts +0 -1
- package/lib/middleware/notificationsMiddleware.js +0 -28
- package/mcp-server/utils/__tests__/cliConfig.test.js +0 -110
- package/mcp-server/utils/cliConfig.d.ts +0 -1
- package/mcp-server/utils/cliConfig.js +0 -12
- /package/{lib/middleware/__test__/commandTargetingUtils.test.d.ts → commands/project/__tests__/lint.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/configMiddleware.test.d.ts → __tests__/commandTargetingUtils.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/gitMiddleware.test.d.ts → __tests__/configMiddleware.test.d.ts} +0 -0
- /package/lib/middleware/{__test__/notificationsMiddleware.test.d.ts → __tests__/gitMiddleware.test.d.ts} +0 -0
- /package/lib/middleware/{__test__ → __tests__}/requestMiddleware.test.d.ts +0 -0
- /package/lib/middleware/{__test__ → __tests__}/requestMiddleware.test.js +0 -0
- /package/lib/middleware/{__test__ → __tests__}/yargsChecksMiddleware.test.d.ts +0 -0
- /package/lib/middleware/{__test__ → __tests__}/yargsChecksMiddleware.test.js +0 -0
- /package/{mcp-server/utils/__tests__/cliConfig.test.d.ts → lib/projects/__tests__/uieLinting.test.d.ts} +0 -0
|
@@ -2,14 +2,20 @@ import { CreateTestAccountTool, } from '../CreateTestAccountTool.js';
|
|
|
2
2
|
import { runCommandInDir } from '../../../utils/project.js';
|
|
3
3
|
import { addFlag } from '../../../utils/command.js';
|
|
4
4
|
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import * as config from '@hubspot/local-dev-lib/config';
|
|
5
7
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
6
8
|
vi.mock('../../../utils/project');
|
|
7
9
|
vi.mock('../../../utils/command');
|
|
8
10
|
vi.mock('../../../utils/toolUsageTracking');
|
|
9
11
|
vi.mock('../../../utils/feedbackTracking');
|
|
12
|
+
vi.mock('fs');
|
|
13
|
+
vi.mock('@hubspot/local-dev-lib/config');
|
|
10
14
|
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
11
15
|
const mockRunCommandInDir = runCommandInDir;
|
|
12
16
|
const mockAddFlag = addFlag;
|
|
17
|
+
const mockReadFileSync = fs.readFileSync;
|
|
18
|
+
const mockGetConfigAccountByName = vi.spyOn(config, 'getConfigAccountByName');
|
|
13
19
|
describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
14
20
|
let mockMcpServer;
|
|
15
21
|
let tool;
|
|
@@ -26,6 +32,14 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
26
32
|
tool = new CreateTestAccountTool(mockMcpServer);
|
|
27
33
|
// Mock addFlag to simulate command building
|
|
28
34
|
mockAddFlag.mockImplementation((command, flag, value) => `${command} --${flag} "${value}"`);
|
|
35
|
+
// Mock fs.readFileSync for config file tests
|
|
36
|
+
mockReadFileSync.mockReturnValue(JSON.stringify({
|
|
37
|
+
accountName: 'TestAccountFromConfig',
|
|
38
|
+
description: 'Test description',
|
|
39
|
+
marketingLevel: 'PROFESSIONAL',
|
|
40
|
+
}));
|
|
41
|
+
// @ts-expect-error breaking things
|
|
42
|
+
mockGetConfigAccountByName.mockReturnValue(undefined);
|
|
29
43
|
});
|
|
30
44
|
describe('register', () => {
|
|
31
45
|
it('should register tool with correct parameters', () => {
|
|
@@ -54,6 +68,12 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
54
68
|
const baseInput = {
|
|
55
69
|
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
56
70
|
configPath: './test-account.json',
|
|
71
|
+
description: 'Test account',
|
|
72
|
+
marketingLevel: 'ENTERPRISE',
|
|
73
|
+
opsLevel: 'ENTERPRISE',
|
|
74
|
+
serviceLevel: 'ENTERPRISE',
|
|
75
|
+
salesLevel: 'ENTERPRISE',
|
|
76
|
+
contentLevel: 'ENTERPRISE',
|
|
57
77
|
};
|
|
58
78
|
it('should create test account with config path', async () => {
|
|
59
79
|
mockRunCommandInDir.mockResolvedValue({
|
|
@@ -65,6 +85,7 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
65
85
|
expect(mockRunCommandInDir).toHaveBeenCalledWith('/test/workspace', 'hs test-account create --config-path "./test-account.json"');
|
|
66
86
|
expect(result).toEqual({
|
|
67
87
|
content: [
|
|
88
|
+
{ type: 'text', text: '/test/workspace' },
|
|
68
89
|
{
|
|
69
90
|
type: 'text',
|
|
70
91
|
text: 'Test account created successfully\nAccount ID: 12345678',
|
|
@@ -81,6 +102,12 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
81
102
|
const input = {
|
|
82
103
|
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
83
104
|
configPath: '/absolute/path/to/config.json',
|
|
105
|
+
description: 'Test account',
|
|
106
|
+
marketingLevel: 'ENTERPRISE',
|
|
107
|
+
opsLevel: 'ENTERPRISE',
|
|
108
|
+
serviceLevel: 'ENTERPRISE',
|
|
109
|
+
salesLevel: 'ENTERPRISE',
|
|
110
|
+
contentLevel: 'ENTERPRISE',
|
|
84
111
|
};
|
|
85
112
|
await tool.handler(input);
|
|
86
113
|
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'config-path', '/absolute/path/to/config.json');
|
|
@@ -96,15 +123,57 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
96
123
|
configPath: './test-account.json',
|
|
97
124
|
name: 'FlagAccount',
|
|
98
125
|
description: 'This should be ignored',
|
|
126
|
+
marketingLevel: 'ENTERPRISE',
|
|
127
|
+
opsLevel: 'ENTERPRISE',
|
|
128
|
+
serviceLevel: 'ENTERPRISE',
|
|
129
|
+
salesLevel: 'ENTERPRISE',
|
|
130
|
+
contentLevel: 'ENTERPRISE',
|
|
99
131
|
};
|
|
100
132
|
await tool.handler(input);
|
|
101
133
|
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'config-path', './test-account.json');
|
|
102
134
|
// Should not call addFlag for name or description
|
|
103
135
|
expect(mockAddFlag).not.toHaveBeenCalledWith(expect.anything(), 'name', expect.anything());
|
|
104
136
|
});
|
|
137
|
+
it('should return helpful error when config file does not exist', async () => {
|
|
138
|
+
mockReadFileSync.mockImplementation(() => {
|
|
139
|
+
throw new Error("ENOENT: no such file or directory, open './missing-config.json'");
|
|
140
|
+
});
|
|
141
|
+
const input = {
|
|
142
|
+
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
143
|
+
configPath: './missing-config.json',
|
|
144
|
+
};
|
|
145
|
+
const result = await tool.handler(input);
|
|
146
|
+
expect(mockRunCommandInDir).not.toHaveBeenCalled();
|
|
147
|
+
expect(result).toEqual({
|
|
148
|
+
content: [
|
|
149
|
+
{
|
|
150
|
+
type: 'text',
|
|
151
|
+
text: expect.stringContaining('Failed to read or parse config file at "./missing-config.json"'),
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
expect(result.content[0]).toHaveProperty('text', expect.stringContaining('Please ensure the file exists and contains valid JSON'));
|
|
156
|
+
});
|
|
157
|
+
it('should return helpful error when config file contains invalid JSON', async () => {
|
|
158
|
+
mockReadFileSync.mockReturnValue('{ invalid json }');
|
|
159
|
+
const input = {
|
|
160
|
+
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
161
|
+
configPath: './invalid-config.json',
|
|
162
|
+
};
|
|
163
|
+
const result = await tool.handler(input);
|
|
164
|
+
expect(mockRunCommandInDir).not.toHaveBeenCalled();
|
|
165
|
+
expect(result).toEqual({
|
|
166
|
+
content: [
|
|
167
|
+
{
|
|
168
|
+
type: 'text',
|
|
169
|
+
text: expect.stringContaining('Failed to read or parse config file at "./invalid-config.json"'),
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
});
|
|
173
|
+
});
|
|
105
174
|
});
|
|
106
175
|
describe('flag-based approach', () => {
|
|
107
|
-
it('should create test account with
|
|
176
|
+
it('should create test account with name and all defaults', async () => {
|
|
108
177
|
mockRunCommandInDir.mockResolvedValue({
|
|
109
178
|
stdout: 'Test account created successfully',
|
|
110
179
|
stderr: '',
|
|
@@ -112,10 +181,30 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
112
181
|
const input = {
|
|
113
182
|
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
114
183
|
name: 'MyTestAccount',
|
|
184
|
+
description: '',
|
|
185
|
+
marketingLevel: 'ENTERPRISE',
|
|
186
|
+
opsLevel: 'ENTERPRISE',
|
|
187
|
+
serviceLevel: 'ENTERPRISE',
|
|
188
|
+
salesLevel: 'ENTERPRISE',
|
|
189
|
+
contentLevel: 'ENTERPRISE',
|
|
115
190
|
};
|
|
116
191
|
await tool.handler(input);
|
|
117
192
|
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'name', 'MyTestAccount');
|
|
118
|
-
|
|
193
|
+
});
|
|
194
|
+
it('should add all flags with defaults when only name is provided', async () => {
|
|
195
|
+
mockRunCommandInDir.mockResolvedValue({
|
|
196
|
+
stdout: 'Test account created successfully',
|
|
197
|
+
stderr: '',
|
|
198
|
+
});
|
|
199
|
+
const input = {
|
|
200
|
+
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
201
|
+
name: 'MyTestAccount',
|
|
202
|
+
};
|
|
203
|
+
await tool.handler(input);
|
|
204
|
+
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'name', 'MyTestAccount');
|
|
205
|
+
// Implementation uses name as fallback for description, and adds all hub levels with ENTERPRISE defaults
|
|
206
|
+
expect(mockAddFlag).toHaveBeenCalledTimes(7);
|
|
207
|
+
expect(mockRunCommandInDir).toHaveBeenCalled();
|
|
119
208
|
});
|
|
120
209
|
it('should create test account with account name and description', async () => {
|
|
121
210
|
mockRunCommandInDir.mockResolvedValue({
|
|
@@ -126,6 +215,11 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
126
215
|
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
127
216
|
name: 'MyTestAccount',
|
|
128
217
|
description: 'Test account for development',
|
|
218
|
+
marketingLevel: 'ENTERPRISE',
|
|
219
|
+
opsLevel: 'ENTERPRISE',
|
|
220
|
+
serviceLevel: 'ENTERPRISE',
|
|
221
|
+
salesLevel: 'ENTERPRISE',
|
|
222
|
+
contentLevel: 'ENTERPRISE',
|
|
129
223
|
};
|
|
130
224
|
await tool.handler(input);
|
|
131
225
|
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'name', 'MyTestAccount');
|
|
@@ -139,9 +233,12 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
139
233
|
const input = {
|
|
140
234
|
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
141
235
|
name: 'MixedTierAccount',
|
|
236
|
+
description: 'Test account',
|
|
142
237
|
marketingLevel: 'PROFESSIONAL',
|
|
143
238
|
salesLevel: 'STARTER',
|
|
144
239
|
contentLevel: 'FREE',
|
|
240
|
+
serviceLevel: 'ENTERPRISE',
|
|
241
|
+
opsLevel: 'ENTERPRISE',
|
|
145
242
|
};
|
|
146
243
|
await tool.handler(input);
|
|
147
244
|
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'name', 'MixedTierAccount');
|
|
@@ -174,10 +271,120 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
174
271
|
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'content-level', 'PROFESSIONAL');
|
|
175
272
|
});
|
|
176
273
|
});
|
|
274
|
+
describe('handler defaults', () => {
|
|
275
|
+
it('should use ENTERPRISE defaults for all hub levels when not specified', async () => {
|
|
276
|
+
mockRunCommandInDir.mockResolvedValue({
|
|
277
|
+
stdout: 'Test account created',
|
|
278
|
+
stderr: '',
|
|
279
|
+
});
|
|
280
|
+
const input = {
|
|
281
|
+
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
282
|
+
name: 'DefaultLevelsAccount',
|
|
283
|
+
description: '',
|
|
284
|
+
marketingLevel: 'ENTERPRISE',
|
|
285
|
+
opsLevel: 'ENTERPRISE',
|
|
286
|
+
serviceLevel: 'ENTERPRISE',
|
|
287
|
+
salesLevel: 'ENTERPRISE',
|
|
288
|
+
contentLevel: 'ENTERPRISE',
|
|
289
|
+
};
|
|
290
|
+
await tool.handler(input);
|
|
291
|
+
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'name', 'DefaultLevelsAccount');
|
|
292
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'marketing-level', 'ENTERPRISE');
|
|
293
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'ops-level', 'ENTERPRISE');
|
|
294
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'service-level', 'ENTERPRISE');
|
|
295
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'sales-level', 'ENTERPRISE');
|
|
296
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'content-level', 'ENTERPRISE');
|
|
297
|
+
});
|
|
298
|
+
it('should use name as fallback for description when description is empty', async () => {
|
|
299
|
+
mockRunCommandInDir.mockResolvedValue({
|
|
300
|
+
stdout: 'Test account created',
|
|
301
|
+
stderr: '',
|
|
302
|
+
});
|
|
303
|
+
const input = {
|
|
304
|
+
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
305
|
+
name: 'NoDescriptionAccount',
|
|
306
|
+
description: '',
|
|
307
|
+
marketingLevel: 'ENTERPRISE',
|
|
308
|
+
opsLevel: 'ENTERPRISE',
|
|
309
|
+
serviceLevel: 'ENTERPRISE',
|
|
310
|
+
salesLevel: 'ENTERPRISE',
|
|
311
|
+
contentLevel: 'ENTERPRISE',
|
|
312
|
+
};
|
|
313
|
+
await tool.handler(input);
|
|
314
|
+
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'name', 'NoDescriptionAccount');
|
|
315
|
+
// Implementation uses name as fallback for description
|
|
316
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'description', 'NoDescriptionAccount');
|
|
317
|
+
});
|
|
318
|
+
it('should use defaults for some hub levels while respecting explicit values', async () => {
|
|
319
|
+
mockRunCommandInDir.mockResolvedValue({
|
|
320
|
+
stdout: 'Test account created',
|
|
321
|
+
stderr: '',
|
|
322
|
+
});
|
|
323
|
+
const input = {
|
|
324
|
+
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
325
|
+
name: 'PartialLevelsAccount',
|
|
326
|
+
description: '',
|
|
327
|
+
marketingLevel: 'FREE',
|
|
328
|
+
salesLevel: 'STARTER',
|
|
329
|
+
opsLevel: 'ENTERPRISE',
|
|
330
|
+
serviceLevel: 'ENTERPRISE',
|
|
331
|
+
contentLevel: 'ENTERPRISE',
|
|
332
|
+
};
|
|
333
|
+
await tool.handler(input);
|
|
334
|
+
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'name', 'PartialLevelsAccount');
|
|
335
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'marketing-level', 'FREE');
|
|
336
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'sales-level', 'STARTER');
|
|
337
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'ops-level', 'ENTERPRISE');
|
|
338
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'service-level', 'ENTERPRISE');
|
|
339
|
+
expect(mockAddFlag).toHaveBeenCalledWith(expect.any(String), 'content-level', 'ENTERPRISE');
|
|
340
|
+
});
|
|
341
|
+
it('should add all hub level flags when defaults are applied', async () => {
|
|
342
|
+
mockRunCommandInDir.mockResolvedValue({
|
|
343
|
+
stdout: 'Test account created with defaults',
|
|
344
|
+
stderr: '',
|
|
345
|
+
});
|
|
346
|
+
const input = {
|
|
347
|
+
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
348
|
+
name: 'MinimalAccount',
|
|
349
|
+
description: '',
|
|
350
|
+
marketingLevel: 'ENTERPRISE',
|
|
351
|
+
opsLevel: 'ENTERPRISE',
|
|
352
|
+
serviceLevel: 'ENTERPRISE',
|
|
353
|
+
salesLevel: 'ENTERPRISE',
|
|
354
|
+
contentLevel: 'ENTERPRISE',
|
|
355
|
+
};
|
|
356
|
+
const result = await tool.handler(input);
|
|
357
|
+
expect(mockRunCommandInDir).toHaveBeenCalled();
|
|
358
|
+
expect(mockAddFlag).toHaveBeenCalledTimes(7);
|
|
359
|
+
expect(result.content[1]).toEqual({
|
|
360
|
+
type: 'text',
|
|
361
|
+
text: 'Test account created with defaults',
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
it('should use ENTERPRISE defaults when values are undefined', async () => {
|
|
365
|
+
mockRunCommandInDir.mockResolvedValue({
|
|
366
|
+
stdout: 'Test account created',
|
|
367
|
+
stderr: '',
|
|
368
|
+
});
|
|
369
|
+
const input = {
|
|
370
|
+
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
371
|
+
name: 'BypassedDefaultsAccount',
|
|
372
|
+
};
|
|
373
|
+
await tool.handler(input);
|
|
374
|
+
expect(mockAddFlag).toHaveBeenCalledWith('hs test-account create', 'name', 'BypassedDefaultsAccount');
|
|
375
|
+
expect(mockAddFlag).toHaveBeenCalledTimes(7);
|
|
376
|
+
});
|
|
377
|
+
});
|
|
177
378
|
describe('interactive mode', () => {
|
|
178
379
|
it('should ask for parameters when neither config nor name provided', async () => {
|
|
179
380
|
const input = {
|
|
180
381
|
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
382
|
+
description: 'Test account',
|
|
383
|
+
marketingLevel: 'ENTERPRISE',
|
|
384
|
+
opsLevel: 'ENTERPRISE',
|
|
385
|
+
serviceLevel: 'ENTERPRISE',
|
|
386
|
+
salesLevel: 'ENTERPRISE',
|
|
387
|
+
contentLevel: 'ENTERPRISE',
|
|
181
388
|
};
|
|
182
389
|
const result = await tool.handler(input);
|
|
183
390
|
// Should NOT run the command
|
|
@@ -202,10 +409,17 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
202
409
|
const input = {
|
|
203
410
|
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
204
411
|
configPath: './test-account.json',
|
|
412
|
+
description: 'Test account',
|
|
413
|
+
marketingLevel: 'ENTERPRISE',
|
|
414
|
+
opsLevel: 'ENTERPRISE',
|
|
415
|
+
serviceLevel: 'ENTERPRISE',
|
|
416
|
+
salesLevel: 'ENTERPRISE',
|
|
417
|
+
contentLevel: 'ENTERPRISE',
|
|
205
418
|
};
|
|
206
419
|
const result = await tool.handler(input);
|
|
207
420
|
expect(result).toEqual({
|
|
208
421
|
content: [
|
|
422
|
+
{ type: 'text', text: '/test/workspace' },
|
|
209
423
|
{ type: 'text', text: 'Test account created successfully' },
|
|
210
424
|
{
|
|
211
425
|
type: 'text',
|
|
@@ -220,10 +434,19 @@ describe('mcp-server/tools/project/CreateTestAccountTool', () => {
|
|
|
220
434
|
const input = {
|
|
221
435
|
absoluteCurrentWorkingDirectory: '/test/workspace',
|
|
222
436
|
configPath: './test-account.json',
|
|
437
|
+
description: 'Test account',
|
|
438
|
+
marketingLevel: 'ENTERPRISE',
|
|
439
|
+
opsLevel: 'ENTERPRISE',
|
|
440
|
+
serviceLevel: 'ENTERPRISE',
|
|
441
|
+
salesLevel: 'ENTERPRISE',
|
|
442
|
+
contentLevel: 'ENTERPRISE',
|
|
223
443
|
};
|
|
224
444
|
const result = await tool.handler(input);
|
|
225
445
|
expect(result).toEqual({
|
|
226
|
-
content: [
|
|
446
|
+
content: [
|
|
447
|
+
{ type: 'text', text: '/test/workspace' },
|
|
448
|
+
{ type: 'text', text: 'Failed to create test account' },
|
|
449
|
+
],
|
|
227
450
|
});
|
|
228
451
|
});
|
|
229
452
|
});
|
|
@@ -2,12 +2,15 @@ import { DocFetchTool } from '../DocFetchTool.js';
|
|
|
2
2
|
import { http } from '@hubspot/local-dev-lib/http/unauthed';
|
|
3
3
|
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
4
4
|
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
5
|
+
import { trackToolUsage } from '../../../utils/toolUsageTracking.js';
|
|
5
6
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
6
7
|
vi.mock('@hubspot/local-dev-lib/http/unauthed');
|
|
7
8
|
vi.mock('@hubspot/local-dev-lib/errors/index');
|
|
8
|
-
vi.mock('
|
|
9
|
+
vi.mock('@hubspot/local-dev-lib/config');
|
|
10
|
+
vi.mock('../../../utils/toolUsageTracking');
|
|
9
11
|
vi.mock('../../../utils/feedbackTracking');
|
|
10
12
|
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
13
|
+
const mockTrackToolUsage = trackToolUsage;
|
|
11
14
|
const mockHttp = http;
|
|
12
15
|
const mockIsHubSpotHttpError = vi.mocked(isHubSpotHttpError);
|
|
13
16
|
describe('mcp-server/tools/project/DocFetchTool', () => {
|
|
@@ -23,6 +26,7 @@ describe('mcp-server/tools/project/DocFetchTool', () => {
|
|
|
23
26
|
mockRegisteredTool = {};
|
|
24
27
|
mockMcpServer.registerTool.mockReturnValue(mockRegisteredTool);
|
|
25
28
|
mockMcpFeedbackRequest.mockResolvedValue('');
|
|
29
|
+
mockTrackToolUsage.mockResolvedValue(undefined);
|
|
26
30
|
tool = new DocFetchTool(mockMcpServer);
|
|
27
31
|
});
|
|
28
32
|
describe('register', () => {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { DocsSearchTool } from '../DocsSearchTool.js';
|
|
2
2
|
import { http } from '@hubspot/local-dev-lib/http';
|
|
3
3
|
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
4
|
-
import {
|
|
4
|
+
import { getConfigDefaultAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
5
5
|
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
6
6
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
7
7
|
vi.mock('@hubspot/local-dev-lib/http');
|
|
8
8
|
vi.mock('@hubspot/local-dev-lib/errors/index');
|
|
9
|
+
vi.mock('@hubspot/local-dev-lib/config');
|
|
9
10
|
vi.mock('../../../utils/toolUsageTracking');
|
|
10
|
-
vi.mock('../../../utils/cliConfig.js');
|
|
11
11
|
vi.mock('../../../utils/feedbackTracking');
|
|
12
12
|
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
13
13
|
const mockHttp = http;
|
|
14
|
-
const mockGetAccountIdFromCliConfig = getAccountIdFromCliConfig;
|
|
15
14
|
const mockIsHubSpotHttpError = vi.mocked(isHubSpotHttpError);
|
|
15
|
+
const mockGetConfigDefaultAccountIfExists = getConfigDefaultAccountIfExists;
|
|
16
16
|
describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
17
17
|
let mockMcpServer;
|
|
18
18
|
let tool;
|
|
@@ -45,7 +45,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
45
45
|
absoluteCurrentWorkingDirectory: '/foo',
|
|
46
46
|
};
|
|
47
47
|
it('should return auth error message when no account ID is found', async () => {
|
|
48
|
-
|
|
48
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue(undefined);
|
|
49
49
|
const result = await tool.handler(mockInput);
|
|
50
50
|
expect(result).toEqual({
|
|
51
51
|
content: [
|
|
@@ -57,7 +57,9 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
57
57
|
});
|
|
58
58
|
});
|
|
59
59
|
it('should return successful results when docs are found', async () => {
|
|
60
|
-
|
|
60
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue({
|
|
61
|
+
accountId: 12345,
|
|
62
|
+
});
|
|
61
63
|
const mockResponse = {
|
|
62
64
|
results: [
|
|
63
65
|
{
|
|
@@ -81,7 +83,7 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
81
83
|
data: mockResponse,
|
|
82
84
|
});
|
|
83
85
|
const result = await tool.handler(mockInput);
|
|
84
|
-
expect(
|
|
86
|
+
expect(mockGetConfigDefaultAccountIfExists).toHaveBeenCalled();
|
|
85
87
|
expect(mockHttp.post).toHaveBeenCalledWith(12345, {
|
|
86
88
|
url: 'dev/docs/llms/v1/docs-search',
|
|
87
89
|
data: {
|
|
@@ -109,7 +111,9 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
109
111
|
expect(resultText).toContain('Test content 2');
|
|
110
112
|
});
|
|
111
113
|
it('should return no results message when no documentation is found', async () => {
|
|
112
|
-
|
|
114
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue({
|
|
115
|
+
accountId: 12345,
|
|
116
|
+
});
|
|
113
117
|
const mockResponse = {
|
|
114
118
|
results: [],
|
|
115
119
|
};
|
|
@@ -128,7 +132,9 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
128
132
|
});
|
|
129
133
|
});
|
|
130
134
|
it('should return no results message when results is null', async () => {
|
|
131
|
-
|
|
135
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue({
|
|
136
|
+
accountId: 12345,
|
|
137
|
+
});
|
|
132
138
|
const mockResponse = {
|
|
133
139
|
results: null,
|
|
134
140
|
};
|
|
@@ -147,7 +153,9 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
147
153
|
});
|
|
148
154
|
});
|
|
149
155
|
it('should handle HubSpot HTTP errors', async () => {
|
|
150
|
-
|
|
156
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue({
|
|
157
|
+
accountId: 12345,
|
|
158
|
+
});
|
|
151
159
|
const mockError = {
|
|
152
160
|
toString: () => 'HubSpot API Error: 404 Not Found',
|
|
153
161
|
};
|
|
@@ -164,7 +172,9 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
164
172
|
});
|
|
165
173
|
});
|
|
166
174
|
it('should handle generic errors', async () => {
|
|
167
|
-
|
|
175
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue({
|
|
176
|
+
accountId: 12345,
|
|
177
|
+
});
|
|
168
178
|
const mockError = new Error('Network error');
|
|
169
179
|
mockHttp.post.mockRejectedValue(mockError);
|
|
170
180
|
mockIsHubSpotHttpError.mockReturnValue(false);
|
|
@@ -179,7 +189,9 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
179
189
|
});
|
|
180
190
|
});
|
|
181
191
|
it('should handle non-Error rejections', async () => {
|
|
182
|
-
|
|
192
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue({
|
|
193
|
+
accountId: 12345,
|
|
194
|
+
});
|
|
183
195
|
mockHttp.post.mockRejectedValue('String error');
|
|
184
196
|
mockIsHubSpotHttpError.mockReturnValue(false);
|
|
185
197
|
const result = await tool.handler(mockInput);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GetApiUsagePatternsByAppIdTool } from '../GetApiUsagePatternsByAppIdTool.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import {
|
|
3
|
+
import { getConfigDefaultAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
4
4
|
import { http } from '@hubspot/local-dev-lib/http';
|
|
5
5
|
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
6
6
|
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
@@ -11,7 +11,7 @@ vi.mock('@hubspot/local-dev-lib/errors/index');
|
|
|
11
11
|
vi.mock('@hubspot/local-dev-lib/config');
|
|
12
12
|
vi.mock('../../../utils/feedbackTracking');
|
|
13
13
|
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
14
|
-
const
|
|
14
|
+
const mockGetConfigDefaultAccountIfExists = getConfigDefaultAccountIfExists;
|
|
15
15
|
const mockHttp = http;
|
|
16
16
|
const mockIsHubSpotHttpError = isHubSpotHttpError;
|
|
17
17
|
describe('mcp-server/tools/project/GetApiUsagePatternsByAppIdTool', () => {
|
|
@@ -89,7 +89,9 @@ describe('mcp-server/tools/project/GetApiUsagePatternsByAppIdTool', () => {
|
|
|
89
89
|
endDate: '2025-12-31',
|
|
90
90
|
};
|
|
91
91
|
beforeEach(() => {
|
|
92
|
-
|
|
92
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue({
|
|
93
|
+
accountId: 123456789,
|
|
94
|
+
});
|
|
93
95
|
mockIsHubSpotHttpError.mockReturnValue(false);
|
|
94
96
|
});
|
|
95
97
|
it('should return API usage patterns successfully', async () => {
|
|
@@ -118,7 +120,7 @@ describe('mcp-server/tools/project/GetApiUsagePatternsByAppIdTool', () => {
|
|
|
118
120
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
121
|
mockHttp.get.mockResolvedValue(mockResponse);
|
|
120
122
|
const result = await tool.handler(input);
|
|
121
|
-
expect(
|
|
123
|
+
expect(mockGetConfigDefaultAccountIfExists).toHaveBeenCalledWith();
|
|
122
124
|
expect(mockHttp.get).toHaveBeenCalledWith(123456789, {
|
|
123
125
|
url: 'app/feature/utilization/public/v3/insights/app/12345/usage-patterns',
|
|
124
126
|
params: {
|
|
@@ -136,7 +138,7 @@ describe('mcp-server/tools/project/GetApiUsagePatternsByAppIdTool', () => {
|
|
|
136
138
|
});
|
|
137
139
|
});
|
|
138
140
|
it('should return error when account ID cannot be determined', async () => {
|
|
139
|
-
|
|
141
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue(undefined);
|
|
140
142
|
const result = await tool.handler(input);
|
|
141
143
|
expect(result).toEqual({
|
|
142
144
|
content: [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GetApplicationInfoTool } from '../GetApplicationInfoTool.js';
|
|
2
|
-
import {
|
|
2
|
+
import { getConfigDefaultAccountIfExists } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { http } from '@hubspot/local-dev-lib/http';
|
|
4
4
|
import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
|
|
5
5
|
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
@@ -10,7 +10,7 @@ vi.mock('@hubspot/local-dev-lib/errors/index');
|
|
|
10
10
|
vi.mock('@hubspot/local-dev-lib/config');
|
|
11
11
|
vi.mock('../../../utils/feedbackTracking');
|
|
12
12
|
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
13
|
-
const
|
|
13
|
+
const mockGetConfigDefaultAccountIfExists = getConfigDefaultAccountIfExists;
|
|
14
14
|
const mockHttp = http;
|
|
15
15
|
const mockIsHubSpotHttpError = isHubSpotHttpError;
|
|
16
16
|
describe('mcp-server/tools/project/GetApplicationInfoTool', () => {
|
|
@@ -42,7 +42,9 @@ describe('mcp-server/tools/project/GetApplicationInfoTool', () => {
|
|
|
42
42
|
describe('handler', () => {
|
|
43
43
|
const input = { absoluteCurrentWorkingDirectory: '/test/dir' };
|
|
44
44
|
beforeEach(() => {
|
|
45
|
-
|
|
45
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue({
|
|
46
|
+
accountId: 123456789,
|
|
47
|
+
});
|
|
46
48
|
mockIsHubSpotHttpError.mockReturnValue(false);
|
|
47
49
|
});
|
|
48
50
|
it('should return application information successfully', async () => {
|
|
@@ -67,7 +69,7 @@ describe('mcp-server/tools/project/GetApplicationInfoTool', () => {
|
|
|
67
69
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
70
|
mockHttp.get.mockResolvedValue(mockResponse);
|
|
69
71
|
const result = await tool.handler(input);
|
|
70
|
-
expect(
|
|
72
|
+
expect(mockGetConfigDefaultAccountIfExists).toHaveBeenCalledWith();
|
|
71
73
|
expect(mockHttp.get).toHaveBeenCalledWith(123456789, {
|
|
72
74
|
url: 'app/feature/utilization/public/v3/insights/apps',
|
|
73
75
|
});
|
|
@@ -81,7 +83,7 @@ describe('mcp-server/tools/project/GetApplicationInfoTool', () => {
|
|
|
81
83
|
});
|
|
82
84
|
});
|
|
83
85
|
it('should return error when account ID cannot be determined', async () => {
|
|
84
|
-
|
|
86
|
+
mockGetConfigDefaultAccountIfExists.mockReturnValue(undefined);
|
|
85
87
|
const result = await tool.handler(input);
|
|
86
88
|
expect(result).toEqual({
|
|
87
89
|
content: [
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|