@adobe/aio-cli-plugin-api-mesh 5.2.3 → 5.2.4-alpha.1

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.
Files changed (38) hide show
  1. package/oclif.manifest.json +1 -1
  2. package/package.json +4 -2
  3. package/src/commands/api-mesh/__tests__/cache-purge.test.js +3 -4
  4. package/src/commands/api-mesh/__tests__/create.test.js +4 -19
  5. package/src/commands/api-mesh/__tests__/delete-log-forwarding.test.js +106 -0
  6. package/src/commands/api-mesh/__tests__/delete.test.js +3 -4
  7. package/src/commands/api-mesh/__tests__/describe.test.js +3 -5
  8. package/src/commands/api-mesh/__tests__/get-log-forwarding.test.js +149 -0
  9. package/src/commands/api-mesh/__tests__/get.test.js +4 -4
  10. package/src/commands/api-mesh/__tests__/log-get-bulk.test.js +21 -215
  11. package/src/commands/api-mesh/__tests__/log-get.test.js +2 -2
  12. package/src/commands/api-mesh/__tests__/log-list.test.js +2 -2
  13. package/src/commands/api-mesh/__tests__/run.test.js +2 -2
  14. package/src/commands/api-mesh/__tests__/set-log-forwarding.test.js +246 -0
  15. package/src/commands/api-mesh/__tests__/status.test.js +2 -2
  16. package/src/commands/api-mesh/__tests__/update.test.js +6 -7
  17. package/src/commands/api-mesh/cache/purge.js +2 -4
  18. package/src/commands/api-mesh/config/delete/log-forwarding.js +80 -0
  19. package/src/commands/api-mesh/config/get/log-forwarding.js +78 -0
  20. package/src/commands/api-mesh/config/set/log-forwarding.js +156 -0
  21. package/src/commands/api-mesh/create.js +21 -4
  22. package/src/commands/api-mesh/delete.js +2 -4
  23. package/src/commands/api-mesh/describe.js +2 -4
  24. package/src/commands/api-mesh/get.js +2 -4
  25. package/src/commands/api-mesh/log-get-bulk.js +6 -27
  26. package/src/commands/api-mesh/log-get.js +2 -4
  27. package/src/commands/api-mesh/log-list.js +2 -4
  28. package/src/commands/api-mesh/run.js +2 -9
  29. package/src/commands/api-mesh/source/__tests__/install.test.js +2 -2
  30. package/src/commands/api-mesh/source/discover.js +2 -9
  31. package/src/commands/api-mesh/source/get.js +1 -8
  32. package/src/commands/api-mesh/source/install.js +2 -3
  33. package/src/commands/api-mesh/status.js +2 -3
  34. package/src/commands/api-mesh/update.js +20 -4
  35. package/src/helpers.js +72 -5
  36. package/src/hooks/initMetadata.js +8 -0
  37. package/src/lib/{devConsole.js → smsClient.js} +299 -0
  38. package/src/utils.js +60 -22
@@ -1,8 +1,8 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const GetBulkLogCommand = require('../log-get-bulk');
4
- const { initRequestId, initSdk, promptConfirm } = require('../../../helpers');
5
- const { getMeshId, getPresignedUrls } = require('../../../lib/devConsole');
4
+ const { initSdk, promptConfirm } = require('../../../helpers');
5
+ const { getMeshId, getPresignedUrls } = require('../../../lib/smsClient');
6
6
  const {
7
7
  suggestCorrectedDateFormat,
8
8
  validateDateTimeRange,
@@ -16,7 +16,7 @@ jest.mock('../../../helpers', () => ({
16
16
  initRequestId: jest.fn().mockResolvedValue({}),
17
17
  promptConfirm: jest.fn().mockResolvedValue(true),
18
18
  }));
19
- jest.mock('../../../lib/devConsole');
19
+ jest.mock('../../../lib/smsClient');
20
20
  jest.mock('../../../classes/logger');
21
21
 
22
22
  describe('GetBulkLogCommand', () => {
@@ -251,7 +251,6 @@ describe('GetBulkLogCommand', () => {
251
251
  const command = new GetBulkLogCommand([], {});
252
252
  await command.run();
253
253
 
254
- expect(initRequestId).toHaveBeenCalled();
255
254
  expect(initSdk).toHaveBeenCalled();
256
255
  expect(getMeshId).toHaveBeenCalledWith('orgCode', 'projectId', 'workspaceId', 'workspaceName');
257
256
  expect(getPresignedUrls).toHaveBeenCalledWith(
@@ -296,194 +295,11 @@ describe('GetBulkLogCommand startTime and endTime validation', () => {
296
295
  );
297
296
  });
298
297
 
299
- describe('GetBulkLogCommand with --past and --from flags', () => {
300
- let parseSpy;
301
-
302
- let now;
303
- let fromDate;
304
- beforeEach(() => {
305
- now = new Date();
306
- fromDate = new Date(now);
307
- fromDate.setDate(fromDate.getDate() - 29); // Set fromDate to 29 days ago
308
- parseSpy = jest.spyOn(GetBulkLogCommand.prototype, 'parse').mockResolvedValue({
309
- flags: {
310
- past: '20mins',
311
- from: fromDate.toISOString().slice(0, 10) + ':12:00:00',
312
- filename: 'test.csv',
313
- ignoreCache: false,
314
- },
315
- });
316
-
317
- initSdk.mockResolvedValue({
318
- imsOrgId: 'orgId',
319
- imsOrgCode: 'orgCode',
320
- projectId: 'projectId',
321
- workspaceId: 'workspaceId',
322
- workspaceName: 'workspaceName',
323
- });
324
- getMeshId.mockResolvedValue('meshId');
325
- getPresignedUrls.mockResolvedValue({
326
- presignedUrls: [{ key: 'log1.csv', url: 'http://example.com/someHash' }],
327
- totalSize: 2048,
328
- });
329
- promptConfirm.mockResolvedValue(true);
330
- global.requestId = 'dummy_request_id';
331
- });
332
-
333
- afterEach(() => {
334
- jest.clearAllMocks();
335
- // clear the date objects
336
- now = null;
337
- fromDate = null;
338
- });
339
-
340
- test('runs with valid --past and --from flags', async () => {
341
- fs.existsSync.mockReturnValue(true);
342
- fs.statSync.mockReturnValue({ size: 0 });
343
-
344
- const mockWriteStream = {
345
- write: jest.fn(),
346
- end: jest.fn(),
347
- on: jest.fn((event, callback) => {
348
- if (event === 'finish') {
349
- callback();
350
- }
351
- }),
352
- };
353
- fs.createWriteStream.mockReturnValue(mockWriteStream);
354
-
355
- const command = new GetBulkLogCommand([], {});
356
- await command.run();
357
-
358
- expect(initRequestId).toHaveBeenCalled();
359
- expect(initSdk).toHaveBeenCalled();
360
- expect(getMeshId).toHaveBeenCalledWith('orgCode', 'projectId', 'workspaceId', 'workspaceName');
361
- expect(getPresignedUrls).toHaveBeenCalledWith(
362
- 'orgCode',
363
- 'projectId',
364
- 'workspaceId',
365
- 'meshId',
366
- expect.any(String),
367
- expect.any(String),
368
- );
369
- expect(fs.createWriteStream).toHaveBeenCalledWith(path.resolve(process.cwd(), 'test.csv'), {
370
- flags: 'a',
371
- });
372
- expect(mockWriteStream.write).toHaveBeenCalled();
373
- expect(mockWriteStream.end).toHaveBeenCalled();
374
- });
375
-
376
- test('throws an error with invalid --from date components', async () => {
377
- parseSpy.mockResolvedValueOnce({
378
- flags: {
379
- past: '20mins',
380
- from: fromDate.toISOString().slice(0, 10) + ':25:61:61',
381
- filename: 'test.csv',
382
- ignoreCache: false,
383
- },
384
- });
385
-
386
- const command = new GetBulkLogCommand([], {});
387
- await expect(command.run()).rejects.toThrow(
388
- 'Invalid date components passed in --from. Correct the date.',
389
- );
390
- });
391
-
392
- test('throws an error with invalid --from date format', async () => {
393
- parseSpy.mockResolvedValueOnce({
394
- flags: {
395
- past: '15mins',
396
- from: fromDate.toISOString().slice(0, 10).replace(/-/g, ':') + ':15:00:00',
397
- filename: 'test.csv',
398
- ignoreCache: false,
399
- },
400
- });
401
-
402
- const command = new GetBulkLogCommand([], {});
403
- await expect(command.run()).rejects.toThrow(
404
- 'Invalid format. Use the format YYYY-MM-DD:HH:MM:SS for --from.',
405
- );
406
- });
407
-
408
- test('runs with valid --past flag without --from', async () => {
409
- parseSpy.mockResolvedValueOnce({
410
- flags: {
411
- past: '15mins',
412
- filename: 'test.csv',
413
- ignoreCache: false,
414
- },
415
- });
416
-
417
- fs.existsSync.mockReturnValue(true);
418
- fs.statSync.mockReturnValue({ size: 0 });
419
-
420
- const command = new GetBulkLogCommand([], {});
421
- await command.run();
422
-
423
- expect(initRequestId).toHaveBeenCalled();
424
- expect(initSdk).toHaveBeenCalled();
425
- expect(getMeshId).toHaveBeenCalledWith('orgCode', 'projectId', 'workspaceId', 'workspaceName');
426
- expect(getPresignedUrls).toHaveBeenCalledWith(
427
- 'orgCode',
428
- 'projectId',
429
- 'workspaceId',
430
- 'meshId',
431
- expect.any(String),
432
- expect.any(String),
433
- );
434
- });
435
-
436
- test('throws an error with edge case for --past duration', async () => {
437
- parseSpy.mockResolvedValueOnce({
438
- flags: {
439
- past: '0s',
440
- from: fromDate.toISOString().slice(0, 10) + ':12:00:00',
441
- filename: 'test.csv',
442
- ignoreCache: false,
443
- },
444
- });
445
-
446
- const command = new GetBulkLogCommand([], {});
447
- await expect(command.run()).rejects.toThrow(
448
- 'Invalid format. The past time window should be in minutes, for example, "20 mins", "15 minutes".',
449
- );
450
- });
451
-
452
- test('runs with edge case for --from date', async () => {
453
- parseSpy.mockResolvedValueOnce({
454
- flags: {
455
- past: '15mins',
456
- from: fromDate.toISOString().slice(0, 10) + ':00:00:00',
457
- filename: 'test.csv',
458
- ignoreCache: false,
459
- },
460
- });
461
-
462
- fs.existsSync.mockReturnValue(true);
463
- fs.statSync.mockReturnValue({ size: 0 });
464
-
465
- const command = new GetBulkLogCommand([], {});
466
- await command.run();
467
-
468
- expect(initRequestId).toHaveBeenCalled();
469
- expect(initSdk).toHaveBeenCalled();
470
- expect(getMeshId).toHaveBeenCalledWith('orgCode', 'projectId', 'workspaceId', 'workspaceName');
471
- expect(getPresignedUrls).toHaveBeenCalledWith(
472
- 'orgCode',
473
- 'projectId',
474
- 'workspaceId',
475
- 'meshId',
476
- expect.any(String),
477
- expect.any(String),
478
- );
479
- });
480
- });
481
-
482
298
  describe('validateDateTimeRange', () => {
483
299
  const testCases = [
484
300
  {
485
- startTime: '2025-03-09T12:00:00Z',
486
- endTime: '2025-03-09T12:45:00Z',
301
+ startTime: new Date(new Date().getTime() - 45 * 60 * 1000).toISOString(),
302
+ endTime: new Date().toISOString(),
487
303
  error:
488
304
  'The maximum duration between startTime and endTime is 30 minutes. The current duration is 0 hours 45 minutes and 0 seconds.',
489
305
  },
@@ -498,18 +314,18 @@ describe('validateDateTimeRange', () => {
498
314
  error: 'Cannot get logs more than 30 days old. Adjust your time range.',
499
315
  },
500
316
  {
501
- startTime: '2025-03-09T12:00:00Z',
502
- endTime: '2025-03-09T12:00:00Z',
503
- error: 'The minimum duration is 1 minutes. The current duration is 0 minutes.',
317
+ startTime: new Date(new Date().getTime() - 20 * 1000).toISOString(),
318
+ endTime: new Date().toISOString(),
319
+ error: 'The minimum duration is 1 minute. The current duration is 20 seconds.',
504
320
  },
505
321
  {
506
- startTime: '2025-03-09T12:30:00Z',
507
- endTime: '2025-03-09T12:00:00Z',
322
+ startTime: new Date().toISOString(),
323
+ endTime: new Date(new Date().getTime() - 0.5 * 60 * 1000).toISOString(),
508
324
  error: 'endTime must be greater than startTime',
509
325
  },
510
326
  {
511
- startTime: '2025-03-09T12:00:00Z',
512
- endTime: '2025-03-09T12:20:00Z',
327
+ startTime: new Date(new Date().getTime() - 20 * 60 * 1000).toISOString(),
328
+ endTime: new Date().toISOString(),
513
329
  error: null,
514
330
  },
515
331
  ];
@@ -528,16 +344,9 @@ describe('validateDateTimeRange', () => {
528
344
 
529
345
  describe('parsePastDuration', () => {
530
346
  const validDurations = [
531
- ['20m', 20 * 60 * 1000],
532
- ['20 m', 20 * 60 * 1000],
533
- ['20min', 20 * 60 * 1000],
534
- ['20 min', 20 * 60 * 1000],
535
- ['20mins', 20 * 60 * 1000],
536
- ['20 mins', 20 * 60 * 1000],
537
- ['20minute', 20 * 60 * 1000],
538
- ['20 minute', 20 * 60 * 1000],
539
- ['20minutes', 20 * 60 * 1000],
540
- ['20 minutes', 20 * 60 * 1000],
347
+ ['20', 20 * 60 * 1000],
348
+ ['30', 30 * 60 * 1000],
349
+ ['15', 15 * 60 * 1000],
541
350
  ];
542
351
 
543
352
  test.each(validDurations)(
@@ -548,14 +357,11 @@ describe('parsePastDuration', () => {
548
357
  },
549
358
  );
550
359
 
551
- const invalidDurations = ['20h', '20 hours', '20s', '20 seconds'];
360
+ const invalidDurations = ['20h', '20 hours', '20s', '20 seconds', 'minutes', 'NaN', 'abc', ''];
552
361
 
553
- test.each(invalidDurations)(
554
- 'throws an error for invalid past duration format "%s"',
555
- invalidPastDuration => {
556
- expect(() => parsePastDuration(invalidPastDuration)).toThrow(
557
- 'Invalid format. The past time window should be in minutes, for example, "20 mins", "15 minutes".',
558
- );
559
- },
560
- );
362
+ test.each(invalidDurations)('throws an error for non-numeric input "%s"', invalidPastDuration => {
363
+ expect(() => parsePastDuration(invalidPastDuration)).toThrow(
364
+ 'Invalid format. The time window must be an integer, for example "20" or "15".',
365
+ );
366
+ });
561
367
  });
@@ -24,7 +24,7 @@ jest.mock('../../../helpers', () => ({
24
24
  initRequestId: jest.fn().mockResolvedValue({}),
25
25
  }));
26
26
 
27
- jest.mock('../../../lib/devConsole');
27
+ jest.mock('../../../lib/smsClient');
28
28
 
29
29
  const mockConsoleCLIInstance = {};
30
30
  const selectedOrg = { id: '1234', code: 'CODE1234@AdobeOrg', name: 'ORG01', type: 'entp' };
@@ -34,7 +34,7 @@ const selectedWorkspace = { id: '123456789', title: 'Workspace01' };
34
34
  const { writeFile } = require('fs/promises');
35
35
  const { initSdk } = require('../../../helpers');
36
36
  const FetchLogsCommand = require('../log-get');
37
- const { getLogsByRayId, getMeshId } = require('../../../lib/devConsole');
37
+ const { getLogsByRayId, getMeshId } = require('../../../lib/smsClient');
38
38
  const os = require('os');
39
39
  let logSpy = null;
40
40
  let errorLogSpy = null;
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const ListLogsCommand = require('../log-list');
3
3
  const { initSdk, promptConfirm } = require('../../../helpers');
4
- const { getMeshId, listLogs } = require('../../../lib/devConsole');
4
+ const { getMeshId, listLogs } = require('../../../lib/smsClient');
5
5
 
6
6
  jest.mock('fs');
7
7
  jest.mock('axios');
@@ -10,7 +10,7 @@ jest.mock('../../../helpers', () => ({
10
10
  initRequestId: jest.fn().mockResolvedValue({}),
11
11
  promptConfirm: jest.fn().mockResolvedValue(true),
12
12
  }));
13
- jest.mock('../../../lib/devConsole');
13
+ jest.mock('../../../lib/smsClient');
14
14
  jest.mock('../../../classes/logger');
15
15
 
16
16
  describe('List Logs Command', () => {
@@ -19,8 +19,8 @@ const {
19
19
  initSdk,
20
20
  writeSecretsFile,
21
21
  } = require('../../../helpers');
22
+ const { getMeshId, getMeshArtifact } = require('../../../lib/smsClient');
22
23
  const { start } = require('../../../wranglerCli');
23
- const { getMeshId, getMeshArtifact } = require('../../../lib/devConsole');
24
24
  require('@adobe-apimesh/mesh-builder');
25
25
 
26
26
  jest.mock('../../../helpers', () => ({
@@ -42,7 +42,7 @@ jest.mock('../../../wranglerCli', () => ({
42
42
  start: jest.fn().mockResolvedValue(),
43
43
  }));
44
44
 
45
- jest.mock('../../../lib/devConsole', () => ({
45
+ jest.mock('../../../lib/smsClient', () => ({
46
46
  getMeshId: jest.fn().mockResolvedValue('mockMeshId'),
47
47
  getMeshArtifact: jest.fn().mockResolvedValue(),
48
48
  }));
@@ -0,0 +1,246 @@
1
+ /*
2
+ Copyright 2021 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+
13
+ const SetLogForwardingCommand = require('../config/set/log-forwarding');
14
+ const {
15
+ initSdk,
16
+ promptConfirm,
17
+ promptSelect,
18
+ promptInput,
19
+ promptInputSecret,
20
+ } = require('../../../helpers');
21
+ const { getMeshId, setLogForwarding } = require('../../../lib/smsClient');
22
+
23
+ jest.mock('../../../helpers', () => ({
24
+ initSdk: jest.fn().mockResolvedValue({}),
25
+ initRequestId: jest.fn().mockResolvedValue({}),
26
+ promptConfirm: jest.fn().mockResolvedValue(true),
27
+ promptSelect: jest.fn().mockResolvedValue('New Relic'),
28
+ promptInput: jest.fn().mockResolvedValue('https://log-api.newrelic.com/log/v1'),
29
+ promptInputSecret: jest.fn().mockResolvedValue('abcdef0123456789abcdef0123456789abcdef01'),
30
+ }));
31
+ jest.mock('../../../lib/smsClient');
32
+ jest.mock('../../../classes/logger');
33
+
34
+ describe('SetLogForwardingCommand', () => {
35
+ let parseSpy;
36
+ let logSpy;
37
+ let errorSpy;
38
+
39
+ beforeEach(() => {
40
+ // Setup spies and mock functions
41
+ parseSpy = jest.spyOn(SetLogForwardingCommand.prototype, 'parse').mockResolvedValue({
42
+ flags: {
43
+ ignoreCache: false,
44
+ autoConfirmAction: false,
45
+ json: false,
46
+ },
47
+ args: [], // Empty args since we are using prompts
48
+ });
49
+
50
+ logSpy = jest.spyOn(SetLogForwardingCommand.prototype, 'log');
51
+ errorSpy = jest.spyOn(SetLogForwardingCommand.prototype, 'error').mockImplementation(() => {
52
+ throw new Error(errorSpy.mock.calls[0][0]);
53
+ });
54
+
55
+ initSdk.mockResolvedValue({
56
+ imsOrgId: 'orgId',
57
+ imsOrgCode: 'orgCode',
58
+ projectId: 'projectId',
59
+ workspaceId: 'workspaceId',
60
+ workspaceName: 'workspaceName',
61
+ });
62
+ getMeshId.mockResolvedValue('meshId');
63
+ setLogForwarding.mockResolvedValue({ success: true, result: true });
64
+ global.requestId = 'dummy_request_id';
65
+ });
66
+
67
+ afterEach(() => {
68
+ jest.clearAllMocks();
69
+ });
70
+
71
+ describe('Test New Relic destination', () => {
72
+ /** Success Scenario */
73
+ test('sets log forwarding with valid parameters', async () => {
74
+ const command = new SetLogForwardingCommand([], {});
75
+ await command.run();
76
+
77
+ expect(promptSelect).toHaveBeenCalledWith('Select log forwarding destination:', [
78
+ 'New Relic',
79
+ ]);
80
+ expect(promptInput).toHaveBeenCalledWith('Enter base URI:');
81
+ expect(promptInputSecret).toHaveBeenCalledWith('Enter license key:');
82
+ expect(setLogForwarding).toHaveBeenCalledWith(
83
+ 'orgCode',
84
+ 'projectId',
85
+ 'workspaceId',
86
+ 'meshId',
87
+ {
88
+ destination: 'newrelic',
89
+ config: {
90
+ baseUri: 'https://log-api.newrelic.com/log/v1',
91
+ licenseKey: 'abcdef0123456789abcdef0123456789abcdef01',
92
+ },
93
+ },
94
+ );
95
+ expect(logSpy).toHaveBeenCalledWith('Log forwarding set successfully for meshId');
96
+ });
97
+
98
+ /** Error Scenarios */
99
+ test('throws an error if mesh ID is not found', async () => {
100
+ getMeshId.mockResolvedValueOnce(null);
101
+
102
+ const command = new SetLogForwardingCommand([], {});
103
+ await expect(command.run()).rejects.toThrow(
104
+ 'Unable to get meshId. No mesh found for Org(orgCode) -> Project(projectId) -> Workspace(workspaceId). Check the details and try again.',
105
+ );
106
+ });
107
+
108
+ /** Input Validation */
109
+ test('throws an error if base URI does not include protocol', async () => {
110
+ promptInput.mockResolvedValueOnce('log-api.newrelic.com/log/v1'); // Missing https://
111
+
112
+ const command = new SetLogForwardingCommand([], {});
113
+ await expect(command.run()).rejects.toThrow(
114
+ 'The URI value must include the protocol (https://)',
115
+ );
116
+ });
117
+
118
+ test('throws an error if license key has wrong format', async () => {
119
+ promptInputSecret.mockResolvedValueOnce('wrongformat'); // Too short
120
+
121
+ const command = new SetLogForwardingCommand([], {});
122
+ await expect(command.run()).rejects.toThrow(
123
+ `The license key is in the wrong format. Expected: 40 characters (received: ${11})`,
124
+ );
125
+ });
126
+
127
+ test('prompts for missing destination', async () => {
128
+ parseSpy.mockResolvedValueOnce({
129
+ flags: {
130
+ // No destination provided
131
+ ignoreCache: false,
132
+ autoConfirmAction: false,
133
+ json: false,
134
+ },
135
+ args: [],
136
+ });
137
+
138
+ const command = new SetLogForwardingCommand([], {});
139
+ await command.run();
140
+
141
+ expect(promptSelect).toHaveBeenCalledWith('Select log forwarding destination:', [
142
+ 'New Relic',
143
+ ]);
144
+ });
145
+
146
+ test('throws an error if destination selection is cancelled', async () => {
147
+ parseSpy.mockResolvedValueOnce({
148
+ flags: {
149
+ // No destination provided
150
+ ignoreCache: false,
151
+ autoConfirmAction: false,
152
+ json: false,
153
+ },
154
+ args: [],
155
+ });
156
+
157
+ promptSelect.mockResolvedValueOnce(null); // User cancels selection
158
+
159
+ const command = new SetLogForwardingCommand([], {});
160
+ await expect(command.run()).rejects.toThrow('Destination is required');
161
+ });
162
+
163
+ test('throws an error if base URI is empty', async () => {
164
+ promptInput.mockResolvedValueOnce(''); // Empty base URI
165
+
166
+ const command = new SetLogForwardingCommand([], {});
167
+ await expect(command.run()).rejects.toThrow('Base URI is required');
168
+ });
169
+
170
+ test('throws an error if license key is empty', async () => {
171
+ promptInputSecret.mockResolvedValueOnce(''); // Empty license key
172
+
173
+ const command = new SetLogForwardingCommand([], {});
174
+ await expect(command.run()).rejects.toThrow('License key is required');
175
+ });
176
+
177
+ test('returns cancellation message when user declines confirmation', async () => {
178
+ promptConfirm.mockResolvedValueOnce(false); // User declines
179
+
180
+ const command = new SetLogForwardingCommand([], {});
181
+ const result = await command.run();
182
+
183
+ expect(result).toBe('set-log-forwarding cancelled');
184
+ expect(setLogForwarding).not.toHaveBeenCalled();
185
+ });
186
+
187
+ /** Flag Handling */
188
+ test('skips confirmation when autoConfirmAction flag is set', async () => {
189
+ parseSpy.mockResolvedValueOnce({
190
+ flags: {
191
+ ignoreCache: false,
192
+ autoConfirmAction: true, // Auto-confirm enabled
193
+ json: false,
194
+ },
195
+ args: [],
196
+ });
197
+
198
+ const command = new SetLogForwardingCommand([], {});
199
+ await command.run();
200
+
201
+ expect(promptConfirm).not.toHaveBeenCalled();
202
+ expect(setLogForwarding).toHaveBeenCalled();
203
+ });
204
+
205
+ test('sets log forwarding with auto-confirmation', async () => {
206
+ parseSpy.mockResolvedValueOnce({
207
+ flags: {
208
+ ignoreCache: false,
209
+ autoConfirmAction: true, // Auto-confirm enabled
210
+ json: false,
211
+ },
212
+ args: [],
213
+ });
214
+
215
+ const command = new SetLogForwardingCommand([], {});
216
+ await command.run();
217
+
218
+ expect(promptConfirm).not.toHaveBeenCalled();
219
+ expect(setLogForwarding).toHaveBeenCalledWith(
220
+ 'orgCode',
221
+ 'projectId',
222
+ 'workspaceId',
223
+ 'meshId',
224
+ {
225
+ destination: 'newrelic',
226
+ config: {
227
+ baseUri: 'https://log-api.newrelic.com/log/v1',
228
+ licenseKey: 'abcdef0123456789abcdef0123456789abcdef01',
229
+ },
230
+ },
231
+ );
232
+ expect(logSpy).toHaveBeenCalledWith('Log forwarding set successfully for meshId');
233
+ });
234
+
235
+ test('logs error message when setLogForwarding fails', async () => {
236
+ const errorMessage = 'Unable to set log forwarding details';
237
+ setLogForwarding.mockRejectedValueOnce(new Error(errorMessage));
238
+
239
+ const command = new SetLogForwardingCommand([], {});
240
+ await expect(command.run()).rejects.toThrow(
241
+ 'Failed to set log forwarding details. Try again. RequestId: dummy_request_id',
242
+ );
243
+ expect(logSpy).toHaveBeenCalledWith(errorMessage);
244
+ });
245
+ });
246
+ });
@@ -8,7 +8,7 @@ const mockMeshId = '00000000-0000-0000-0000-000000000000';
8
8
  global.requestId = 'dummy_request_id';
9
9
 
10
10
  // Create mock modules and functions
11
- jest.mock('../../../lib/devConsole');
11
+ jest.mock('../../../lib/smsClient');
12
12
  jest.mock('../../../helpers');
13
13
  const parseSpy = jest.spyOn(StatusCommand.prototype, 'parse');
14
14
  const logSpy = jest.spyOn(StatusCommand.prototype, 'log');
@@ -16,7 +16,7 @@ const errorLogSpy = jest.spyOn(StatusCommand.prototype, 'error');
16
16
 
17
17
  // Prepare mocks
18
18
  const { initSdk } = require('../../../helpers');
19
- const { getMeshId, getMesh, getMeshDeployments } = require('../../../lib/devConsole');
19
+ const { getMeshId, getMesh, getMeshDeployments } = require('../../../lib/smsClient');
20
20
  initSdk.mockResolvedValue({
21
21
  imsOrgId: mockOrg.id,
22
22
  imsOrgCode: mockOrg.code,
@@ -24,7 +24,7 @@ jest.mock('@adobe/aio-cli-lib-console', () => ({
24
24
  cleanStdOut: jest.fn(),
25
25
  }));
26
26
  jest.mock('@adobe/aio-lib-ims');
27
- jest.mock('../../../lib/devConsole');
27
+ jest.mock('../../../lib/smsClient');
28
28
 
29
29
  const mockConsoleCLIInstance = {};
30
30
 
@@ -35,8 +35,8 @@ const selectedWorkspace = { id: '123456789', title: 'Workspace01' };
35
35
  const { readFile } = require('fs/promises');
36
36
 
37
37
  const UpdateCommand = require('../update');
38
- const { initSdk, initRequestId, promptConfirm, importFiles } = require('../../../helpers');
39
- const { getMeshId, updateMesh } = require('../../../lib/devConsole');
38
+ const { initSdk, promptConfirm, importFiles } = require('../../../helpers');
39
+ const { getMeshId, updateMesh } = require('../../../lib/smsClient');
40
40
 
41
41
  let logSpy = null;
42
42
  let errorLogSpy = null;
@@ -110,7 +110,7 @@ describe('update command tests', () => {
110
110
  "status": "success",
111
111
  }
112
112
  `);
113
- expect(initRequestId).toHaveBeenCalled();
113
+
114
114
  expect(initSdk).toHaveBeenCalledWith({
115
115
  ignoreCache: true,
116
116
  });
@@ -169,7 +169,7 @@ describe('update command tests', () => {
169
169
  "status": "success",
170
170
  }
171
171
  `);
172
- expect(initRequestId).toHaveBeenCalled();
172
+
173
173
  expect(initSdk).toHaveBeenCalledWith({
174
174
  ignoreCache: true,
175
175
  });
@@ -228,7 +228,7 @@ describe('update command tests', () => {
228
228
  "status": "success",
229
229
  }
230
230
  `);
231
- expect(initRequestId).toHaveBeenCalled();
231
+
232
232
  expect(promptConfirm).not.toHaveBeenCalled();
233
233
  expect(initSdk).toHaveBeenCalledWith({
234
234
  ignoreCache: true,
@@ -554,7 +554,6 @@ describe('update command tests', () => {
554
554
 
555
555
  const output = await UpdateCommand.run();
556
556
 
557
- expect(initRequestId).toHaveBeenCalled();
558
557
  expect(updateMesh.mock.calls[0]).toMatchInlineSnapshot(`
559
558
  [
560
559
  "CODE1234@AdobeOrg",
@@ -12,13 +12,13 @@ governing permissions and limitations under the License.
12
12
  const { Command } = require('@oclif/command');
13
13
 
14
14
  const logger = require('../../../classes/logger');
15
- const { initSdk, initRequestId, promptConfirm } = require('../../../helpers');
15
+ const { initSdk, promptConfirm } = require('../../../helpers');
16
16
  const {
17
17
  ignoreCacheFlag,
18
18
  autoConfirmActionFlag,
19
19
  cachePurgeAllActionFlag,
20
20
  } = require('../../../utils');
21
- const { getMeshId, cachePurge } = require('../../../lib/devConsole');
21
+ const { getMeshId, cachePurge } = require('../../../lib/smsClient');
22
22
 
23
23
  require('dotenv').config();
24
24
 
@@ -30,8 +30,6 @@ class CachePurgeCommand extends Command {
30
30
  };
31
31
 
32
32
  async run() {
33
- await initRequestId();
34
-
35
33
  logger.info(`RequestId: ${global.requestId}`);
36
34
 
37
35
  const { flags } = await this.parse(CachePurgeCommand);