tm1npm 1.6.0 → 2.0.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/lib/services/ApplicationService.d.ts.map +1 -1
  3. package/lib/services/AsyncOperationService.d.ts +8 -1
  4. package/lib/services/AsyncOperationService.d.ts.map +1 -1
  5. package/lib/services/AsyncOperationService.js +69 -26
  6. package/lib/services/FileService.d.ts.map +1 -1
  7. package/lib/services/ProcessService.d.ts +18 -13
  8. package/lib/services/ProcessService.d.ts.map +1 -1
  9. package/lib/services/ProcessService.js +28 -17
  10. package/lib/services/RestService.d.ts +213 -25
  11. package/lib/services/RestService.d.ts.map +1 -1
  12. package/lib/services/RestService.js +840 -271
  13. package/lib/services/TM1Service.d.ts +42 -1
  14. package/lib/services/TM1Service.d.ts.map +1 -1
  15. package/lib/services/TM1Service.js +94 -4
  16. package/lib/tests/asyncOperationService.test.js +51 -45
  17. package/lib/tests/processService.comprehensive.test.js +2 -2
  18. package/lib/tests/processService.test.js +20 -6
  19. package/lib/tests/restService.test.d.ts +0 -4
  20. package/lib/tests/restService.test.d.ts.map +1 -1
  21. package/lib/tests/restService.test.js +1558 -143
  22. package/lib/tests/tm1Service.test.js +80 -8
  23. package/package.json +1 -1
  24. package/src/services/ApplicationService.ts +4 -4
  25. package/src/services/AsyncOperationService.ts +76 -29
  26. package/src/services/FileService.ts +3 -3
  27. package/src/services/ProcessService.ts +67 -37
  28. package/src/services/RestService.ts +1020 -278
  29. package/src/services/TM1Service.ts +124 -6
  30. package/src/tests/asyncOperationService.test.ts +52 -48
  31. package/src/tests/processService.comprehensive.test.ts +3 -3
  32. package/src/tests/processService.test.ts +21 -9
  33. package/src/tests/restService.test.ts +1844 -139
  34. package/src/tests/tm1Service.test.ts +95 -11
@@ -8,11 +8,36 @@ import { BulkService } from './BulkService';
8
8
  import { AsyncOperationService } from './AsyncOperationService';
9
9
  import { PowerBiService } from './PowerBiService';
10
10
  import { ApplicationService } from './ApplicationService';
11
+ import { AnnotationService } from './AnnotationService';
12
+ import { ChoreService } from './ChoreService';
13
+ import { GitService } from './GitService';
14
+ import { SandboxService } from './SandboxService';
15
+ import { JobService } from './JobService';
16
+ import { UserService } from './UserService';
17
+ import { ThreadService } from './ThreadService';
18
+ import { TransactionLogService } from './TransactionLogService';
19
+ import { MessageLogService } from './MessageLogService';
20
+ import { ConfigurationService } from './ConfigurationService';
21
+ import { AuditLogService } from './AuditLogService';
22
+ import { LoggerService } from './LoggerService';
23
+ import { User } from '../objects/User';
11
24
  import { CubeService, ElementService, CellService, ProcessService, ViewService, SecurityService, FileService, SessionService, ServerService, MonitoringService } from './index';
12
25
  export declare class TM1Service {
13
26
  private _tm1Rest;
14
27
  private _server?;
15
28
  private _monitoring?;
29
+ private _annotations?;
30
+ private _chores?;
31
+ private _git?;
32
+ private _sandboxes?;
33
+ private _jobs?;
34
+ private _users?;
35
+ private _threads?;
36
+ private _transactionLogs?;
37
+ private _messageLogs?;
38
+ private _configuration?;
39
+ private _auditLogs?;
40
+ private _loggers?;
16
41
  dimensions: DimensionService;
17
42
  hierarchies: HierarchyService;
18
43
  subsets: SubsetService;
@@ -36,14 +61,30 @@ export declare class TM1Service {
36
61
  disconnect(): Promise<void>;
37
62
  get server(): ServerService;
38
63
  get monitoring(): MonitoringService;
39
- whoami(): Promise<string>;
64
+ get annotations(): AnnotationService;
65
+ get chores(): ChoreService;
66
+ get git(): GitService;
67
+ get sandboxes(): SandboxService;
68
+ get jobs(): JobService;
69
+ get users(): UserService;
70
+ get threads(): ThreadService;
71
+ get transactionLogs(): TransactionLogService;
72
+ get messageLogs(): MessageLogService;
73
+ get configuration(): ConfigurationService;
74
+ get auditLogs(): AuditLogService;
75
+ get loggers(): LoggerService;
76
+ whoami(): Promise<User>;
40
77
  getMetadata(): Promise<any>;
78
+ get version(): string | undefined;
41
79
  getVersion(): Promise<string>;
42
80
  get connection(): RestService;
43
81
  getSessionId(): string | undefined;
44
82
  setSandbox(sandboxName?: string): void;
45
83
  getSandbox(): string | undefined;
46
84
  isLoggedIn(): boolean;
85
+ /** Reconnects without teardown. Use reAuthenticate() for full disconnect+reconnect. */
86
+ reConnect(): Promise<void>;
87
+ /** Full teardown + reconnect. If disconnect() throws, connect() is not attempted. */
47
88
  reAuthenticate(): Promise<void>;
48
89
  static create(config: RestServiceConfig): Promise<TM1Service>;
49
90
  dispose(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"TM1Service.d.ts","sourceRoot":"","sources":["../../src/services/TM1Service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACH,WAAW,EACX,cAAc,EACd,WAAW,EACX,cAAc,EACd,WAAW,EACX,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACpB,MAAM,SAAS,CAAC;AAEjB,qBAAa,UAAU;IACnB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,WAAW,CAAC,CAAoB;IAEjC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,eAAe,EAAE,qBAAqB,CAAC;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,YAAY,EAAE,kBAAkB,CAAC;gBAE5B,MAAM,EAAE,iBAAiB;IA4BxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxC,IAAW,MAAM,IAAI,aAAa,CAKjC;IAED,IAAW,UAAU,IAAI,iBAAiB,CAKzC;IAEY,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAKzB,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC;IAK3B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAK1C,IAAW,UAAU,IAAI,WAAW,CAEnC;IAEM,YAAY,IAAI,MAAM,GAAG,SAAS;IAIlC,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAItC,UAAU,IAAI,MAAM,GAAG,SAAS;IAIhC,UAAU,IAAI,OAAO;IAIf,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;WAMxB,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAO7D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAOxC"}
1
+ {"version":3,"file":"TM1Service.d.ts","sourceRoot":"","sources":["../../src/services/TM1Service.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,18 @@ const BulkService_1 = require("./BulkService");
11
11
  const AsyncOperationService_1 = require("./AsyncOperationService");
12
12
  const PowerBiService_1 = require("./PowerBiService");
13
13
  const ApplicationService_1 = require("./ApplicationService");
14
+ const AnnotationService_1 = require("./AnnotationService");
15
+ const ChoreService_1 = require("./ChoreService");
16
+ const GitService_1 = require("./GitService");
17
+ const SandboxService_1 = require("./SandboxService");
18
+ const JobService_1 = require("./JobService");
19
+ const UserService_1 = require("./UserService");
20
+ const ThreadService_1 = require("./ThreadService");
21
+ const TransactionLogService_1 = require("./TransactionLogService");
22
+ const MessageLogService_1 = require("./MessageLogService");
23
+ const ConfigurationService_1 = require("./ConfigurationService");
24
+ const AuditLogService_1 = require("./AuditLogService");
25
+ const LoggerService_1 = require("./LoggerService");
14
26
  const index_1 = require("./index");
15
27
  class TM1Service {
16
28
  constructor(config) {
@@ -58,17 +70,90 @@ class TM1Service {
58
70
  }
59
71
  return this._monitoring;
60
72
  }
73
+ get annotations() {
74
+ if (!this._annotations) {
75
+ this._annotations = new AnnotationService_1.AnnotationService(this._tm1Rest);
76
+ }
77
+ return this._annotations;
78
+ }
79
+ get chores() {
80
+ if (!this._chores) {
81
+ this._chores = new ChoreService_1.ChoreService(this._tm1Rest);
82
+ }
83
+ return this._chores;
84
+ }
85
+ get git() {
86
+ if (!this._git) {
87
+ this._git = new GitService_1.GitService(this._tm1Rest);
88
+ }
89
+ return this._git;
90
+ }
91
+ get sandboxes() {
92
+ if (!this._sandboxes) {
93
+ this._sandboxes = new SandboxService_1.SandboxService(this._tm1Rest);
94
+ }
95
+ return this._sandboxes;
96
+ }
97
+ get jobs() {
98
+ if (!this._jobs) {
99
+ this._jobs = new JobService_1.JobService(this._tm1Rest);
100
+ }
101
+ return this._jobs;
102
+ }
103
+ get users() {
104
+ if (!this._users) {
105
+ this._users = new UserService_1.UserService(this._tm1Rest);
106
+ }
107
+ return this._users;
108
+ }
109
+ get threads() {
110
+ if (!this._threads) {
111
+ this._threads = new ThreadService_1.ThreadService(this._tm1Rest);
112
+ }
113
+ return this._threads;
114
+ }
115
+ get transactionLogs() {
116
+ if (!this._transactionLogs) {
117
+ this._transactionLogs = new TransactionLogService_1.TransactionLogService(this._tm1Rest);
118
+ }
119
+ return this._transactionLogs;
120
+ }
121
+ get messageLogs() {
122
+ if (!this._messageLogs) {
123
+ this._messageLogs = new MessageLogService_1.MessageLogService(this._tm1Rest);
124
+ }
125
+ return this._messageLogs;
126
+ }
127
+ get configuration() {
128
+ if (!this._configuration) {
129
+ this._configuration = new ConfigurationService_1.ConfigurationService(this._tm1Rest);
130
+ }
131
+ return this._configuration;
132
+ }
133
+ get auditLogs() {
134
+ if (!this._auditLogs) {
135
+ this._auditLogs = new AuditLogService_1.AuditLogService(this._tm1Rest);
136
+ }
137
+ return this._auditLogs;
138
+ }
139
+ get loggers() {
140
+ if (!this._loggers) {
141
+ this._loggers = new LoggerService_1.LoggerService(this._tm1Rest);
142
+ }
143
+ return this._loggers;
144
+ }
61
145
  async whoami() {
62
- const user = await this.security.getCurrentUser();
63
- return user.name;
146
+ return await this.security.getCurrentUser();
64
147
  }
65
148
  async getMetadata() {
66
149
  const response = await this._tm1Rest.get('/$metadata');
67
150
  return response.data;
68
151
  }
152
+ get version() {
153
+ return this._tm1Rest.version;
154
+ }
69
155
  async getVersion() {
70
- const response = await this._tm1Rest.get('/Configuration/ProductVersion');
71
- return response.data.value;
156
+ return await this._tm1Rest.getVersion();
72
157
  }
73
158
  get connection() {
74
159
  return this._tm1Rest;
@@ -85,6 +170,11 @@ class TM1Service {
85
170
  isLoggedIn() {
86
171
  return this._tm1Rest.isLoggedIn();
87
172
  }
173
+ /** Reconnects without teardown. Use reAuthenticate() for full disconnect+reconnect. */
174
+ async reConnect() {
175
+ await this._tm1Rest.connect();
176
+ }
177
+ /** Full teardown + reconnect. If disconnect() throws, connect() is not attempted. */
88
178
  async reAuthenticate() {
89
179
  await this._tm1Rest.disconnect();
90
180
  await this._tm1Rest.connect();
@@ -273,8 +273,11 @@ describe('AsyncOperationService', () => {
273
273
  name: 'View1'
274
274
  });
275
275
  asyncService.updateOperationStatus(id3, AsyncOperationService_1.OperationStatus.COMPLETED);
276
+ // HTTP 202 = still running on the /_async endpoint.
276
277
  mockRestService.get = jest.fn().mockResolvedValue({
277
- data: { Status: 'Running' }
278
+ status: 202,
279
+ headers: {},
280
+ data: {}
278
281
  });
279
282
  const activeOps = await asyncService.listActiveAsyncOperations();
280
283
  expect(activeOps.length).toBe(2);
@@ -479,70 +482,73 @@ describe('AsyncOperationService', () => {
479
482
  expect(callback).toHaveBeenCalled();
480
483
  });
481
484
  });
485
+ // Status is inferred from the /_async('{id}') HTTP status code and the
486
+ // v12 `asyncresult` header; there is no `.Status` envelope on the new endpoint.
487
+ // These tests bypass createAsyncOperation (which tags operations as
488
+ // trackedLocally: true) to exercise the server-polling branch directly.
482
489
  describe('Server Status Mapping', () => {
483
- test('should map CompletedSuccessfully to COMPLETED', async () => {
484
- const operationId = await asyncService.createAsyncOperation({
490
+ const injectServerOperation = (id) => {
491
+ asyncService.operations.set(id, {
492
+ id,
485
493
  type: AsyncOperationService_1.OperationType.PROCESS_EXECUTION,
486
- name: 'TestProcess'
494
+ name: 'TestProcess',
495
+ status: AsyncOperationService_1.OperationStatus.RUNNING,
496
+ startTime: new Date(),
497
+ trackedLocally: false
487
498
  });
488
- asyncService.updateOperationStatus(operationId, AsyncOperationService_1.OperationStatus.RUNNING);
499
+ };
500
+ test('should map HTTP 200 without asyncresult header to COMPLETED', async () => {
501
+ injectServerOperation('srv-1');
489
502
  mockRestService.get = jest.fn().mockResolvedValue({
490
- data: { Status: 'CompletedSuccessfully', Result: { value: 42 } }
503
+ status: 200,
504
+ headers: {},
505
+ data: { value: 42 }
491
506
  });
492
- const status = await asyncService.getAsyncOperationStatus(operationId);
507
+ const status = await asyncService.getAsyncOperationStatus('srv-1');
493
508
  expect(status).toBe(AsyncOperationService_1.OperationStatus.COMPLETED);
494
- const operation = asyncService.getOperation(operationId);
509
+ const operation = asyncService.getOperation('srv-1');
495
510
  expect(operation === null || operation === void 0 ? void 0 : operation.result).toEqual({ value: 42 });
496
511
  });
497
- test('should map CompletedWithErrors to FAILED', async () => {
498
- const operationId = await asyncService.createAsyncOperation({
499
- type: AsyncOperationService_1.OperationType.PROCESS_EXECUTION,
500
- name: 'TestProcess'
501
- });
502
- asyncService.updateOperationStatus(operationId, AsyncOperationService_1.OperationStatus.RUNNING);
512
+ test('should map HTTP 200 with non-2xx asyncresult header to FAILED', async () => {
513
+ injectServerOperation('srv-2');
503
514
  mockRestService.get = jest.fn().mockResolvedValue({
504
- data: { Status: 'CompletedWithErrors', Error: 'Process failed at line 10' }
515
+ status: 200,
516
+ headers: { asyncresult: '500 Internal Server Error' },
517
+ data: {}
505
518
  });
506
- const status = await asyncService.getAsyncOperationStatus(operationId);
519
+ const status = await asyncService.getAsyncOperationStatus('srv-2');
520
+ expect(status).toBe(AsyncOperationService_1.OperationStatus.FAILED);
521
+ const operation = asyncService.getOperation('srv-2');
522
+ expect(operation === null || operation === void 0 ? void 0 : operation.error).toBe('500 Internal Server Error');
523
+ });
524
+ test('should map thrown TM1RestException to FAILED', async () => {
525
+ injectServerOperation('srv-3');
526
+ const { TM1RestException } = require('../exceptions/TM1Exception');
527
+ mockRestService.get = jest.fn().mockRejectedValue(new TM1RestException('Server error', 500));
528
+ const status = await asyncService.getAsyncOperationStatus('srv-3');
507
529
  expect(status).toBe(AsyncOperationService_1.OperationStatus.FAILED);
508
- const operation = asyncService.getOperation(operationId);
509
- expect(operation === null || operation === void 0 ? void 0 : operation.error).toBe('Process failed at line 10');
510
- });
511
- test('should map Cancelled status correctly', async () => {
512
- const operationId = await asyncService.createAsyncOperation({
513
- type: AsyncOperationService_1.OperationType.PROCESS_EXECUTION,
514
- name: 'TestProcess'
515
- });
516
- asyncService.updateOperationStatus(operationId, AsyncOperationService_1.OperationStatus.RUNNING);
517
- mockRestService.get = jest.fn().mockResolvedValue({
518
- data: { Status: 'Cancelled' }
519
- });
520
- const status = await asyncService.getAsyncOperationStatus(operationId);
521
- expect(status).toBe(AsyncOperationService_1.OperationStatus.CANCELLED);
522
530
  });
523
- test('should map Timeout status correctly', async () => {
524
- const operationId = await asyncService.createAsyncOperation({
525
- type: AsyncOperationService_1.OperationType.PROCESS_EXECUTION,
526
- name: 'TestProcess'
527
- });
528
- asyncService.updateOperationStatus(operationId, AsyncOperationService_1.OperationStatus.RUNNING);
531
+ test('should map HTTP 202 to RUNNING', async () => {
532
+ injectServerOperation('srv-4');
529
533
  mockRestService.get = jest.fn().mockResolvedValue({
530
- data: { Status: 'Timeout' }
534
+ status: 202,
535
+ headers: {},
536
+ data: {}
531
537
  });
532
- const status = await asyncService.getAsyncOperationStatus(operationId);
533
- expect(status).toBe(AsyncOperationService_1.OperationStatus.TIMEOUT);
538
+ const status = await asyncService.getAsyncOperationStatus('srv-4');
539
+ expect(status).toBe(AsyncOperationService_1.OperationStatus.RUNNING);
534
540
  });
535
- test('should default to PENDING for unknown status', async () => {
541
+ test('locally-tracked operations skip server polling and return cached status', async () => {
536
542
  const operationId = await asyncService.createAsyncOperation({
537
543
  type: AsyncOperationService_1.OperationType.PROCESS_EXECUTION,
538
- name: 'TestProcess'
544
+ name: 'LocalProcess'
539
545
  });
540
546
  asyncService.updateOperationStatus(operationId, AsyncOperationService_1.OperationStatus.RUNNING);
541
- mockRestService.get = jest.fn().mockResolvedValue({
542
- data: { Status: 'UnknownStatus' }
543
- });
547
+ const getSpy = jest.fn();
548
+ mockRestService.get = getSpy;
544
549
  const status = await asyncService.getAsyncOperationStatus(operationId);
545
- expect(status).toBe(AsyncOperationService_1.OperationStatus.PENDING);
550
+ expect(status).toBe(AsyncOperationService_1.OperationStatus.RUNNING);
551
+ expect(getSpy).not.toHaveBeenCalled();
546
552
  });
547
553
  });
548
554
  describe('Concurrent Operations', () => {
@@ -222,7 +222,7 @@ describe('ProcessService - Comprehensive Tests', () => {
222
222
  mockRestService.post.mockResolvedValue(mockResponse(returnData));
223
223
  const result = await processService.executeWithReturn('TestProcess', {}, 30);
224
224
  expect(result).toEqual(mockResponse(returnData));
225
- expect(mockRestService.post).toHaveBeenCalledWith("/Processes('TestProcess')/tm1.ExecuteWithReturn?$expand=*", "{}", { timeout: 30000 });
225
+ expect(mockRestService.post).toHaveBeenCalledWith("/Processes('TestProcess')/tm1.ExecuteWithReturn?$expand=*", "{}", { timeout: 30 });
226
226
  });
227
227
  test('should execute process with return data extraction', async () => {
228
228
  const returnData = {
@@ -654,7 +654,7 @@ describe('ProcessService - Comprehensive Tests', () => {
654
654
  const debugResponse = { ID: 'ctx-003', Breakpoints: [], CallStack: [] };
655
655
  mockRestService.post.mockResolvedValue(mockResponse(debugResponse));
656
656
  await processService.debugProcess('TestProcess', 60);
657
- expect(mockRestService.post).toHaveBeenCalledWith(expect.any(String), expect.any(String), { timeout: 60000 });
657
+ expect(mockRestService.post).toHaveBeenCalledWith(expect.any(String), expect.any(String), { timeout: 60 });
658
658
  });
659
659
  test('debugAddBreakpoints should POST breakpoints array to Breakpoints endpoint', async () => {
660
660
  mockRestService.post.mockResolvedValue(mockResponse({}));
@@ -353,9 +353,16 @@ describe('ProcessService Tests', () => {
353
353
  });
354
354
  describe('Process Async Polling', () => {
355
355
  test('pollExecuteWithReturn should return parsed result on success', async () => {
356
+ // retrieve_async_response returns an AxiosResponse; the execute summary
357
+ // lives in .data. Tests that mocked the raw body directly did not
358
+ // reflect production shape and silently passed against the untyped
359
+ // parser signature.
356
360
  mockRestService.retrieve_async_response = jest.fn().mockResolvedValue({
357
- ProcessExecuteStatusCode: 'CompletedSuccessfully',
358
- ErrorLogFile: null
361
+ status: 200,
362
+ data: {
363
+ ProcessExecuteStatusCode: 'CompletedSuccessfully',
364
+ ErrorLogFile: null
365
+ }
359
366
  });
360
367
  const result = await processService.pollExecuteWithReturn('async-001');
361
368
  expect(result).toEqual([true, 'CompletedSuccessfully', null]);
@@ -363,8 +370,11 @@ describe('ProcessService Tests', () => {
363
370
  });
364
371
  test('pollExecuteWithReturn should return error log file when present', async () => {
365
372
  mockRestService.retrieve_async_response = jest.fn().mockResolvedValue({
366
- ProcessExecuteStatusCode: 'CompletedWithMessages',
367
- ErrorLogFile: { Filename: 'TM1ProcessError_20240101.log' }
373
+ status: 200,
374
+ data: {
375
+ ProcessExecuteStatusCode: 'CompletedWithMessages',
376
+ ErrorLogFile: { Filename: 'TM1ProcessError_20240101.log' }
377
+ }
368
378
  });
369
379
  const result = await processService.pollExecuteWithReturn('async-002');
370
380
  expect(result).toEqual([false, 'CompletedWithMessages', 'TM1ProcessError_20240101.log']);
@@ -376,8 +386,12 @@ describe('ProcessService Tests', () => {
376
386
  expect(result).toBeNull();
377
387
  });
378
388
  test('pollExecuteWithReturn should return null for 202 (accepted/pending)', async () => {
379
- const { TM1RestException } = require('../exceptions/TM1Exception');
380
- mockRestService.retrieve_async_response = jest.fn().mockRejectedValue(new TM1RestException('Accepted', 202));
389
+ // After the #80 refactor retrieve_async_response returns the raw AxiosResponse
390
+ // instead of throwing on 202; the pending path is now signalled by status === 202.
391
+ mockRestService.retrieve_async_response = jest.fn().mockResolvedValue({
392
+ status: 202,
393
+ data: {}
394
+ });
381
395
  const result = await processService.pollExecuteWithReturn('async-004');
382
396
  expect(result).toBeNull();
383
397
  });
@@ -1,6 +1,2 @@
1
- /**
2
- * RestService Tests for tm1npm
3
- * Comprehensive tests for TM1 REST API operations with proper mocking
4
- */
5
1
  export {};
6
2
  //# sourceMappingURL=restService.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"restService.test.d.ts","sourceRoot":"","sources":["../../src/tests/restService.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
1
+ {"version":3,"file":"restService.test.d.ts","sourceRoot":"","sources":["../../src/tests/restService.test.ts"],"names":[],"mappings":""}