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.
- package/CHANGELOG.md +89 -0
- package/lib/services/ApplicationService.d.ts.map +1 -1
- package/lib/services/AsyncOperationService.d.ts +8 -1
- package/lib/services/AsyncOperationService.d.ts.map +1 -1
- package/lib/services/AsyncOperationService.js +69 -26
- package/lib/services/FileService.d.ts.map +1 -1
- package/lib/services/ProcessService.d.ts +18 -13
- package/lib/services/ProcessService.d.ts.map +1 -1
- package/lib/services/ProcessService.js +28 -17
- package/lib/services/RestService.d.ts +213 -25
- package/lib/services/RestService.d.ts.map +1 -1
- package/lib/services/RestService.js +840 -271
- package/lib/services/TM1Service.d.ts +42 -1
- package/lib/services/TM1Service.d.ts.map +1 -1
- package/lib/services/TM1Service.js +94 -4
- package/lib/tests/asyncOperationService.test.js +51 -45
- package/lib/tests/processService.comprehensive.test.js +2 -2
- package/lib/tests/processService.test.js +20 -6
- package/lib/tests/restService.test.d.ts +0 -4
- package/lib/tests/restService.test.d.ts.map +1 -1
- package/lib/tests/restService.test.js +1558 -143
- package/lib/tests/tm1Service.test.js +80 -8
- package/package.json +1 -1
- package/src/services/ApplicationService.ts +4 -4
- package/src/services/AsyncOperationService.ts +76 -29
- package/src/services/FileService.ts +3 -3
- package/src/services/ProcessService.ts +67 -37
- package/src/services/RestService.ts +1020 -278
- package/src/services/TM1Service.ts +124 -6
- package/src/tests/asyncOperationService.test.ts +52 -48
- package/src/tests/processService.comprehensive.test.ts +3 -3
- package/src/tests/processService.test.ts +21 -9
- package/src/tests/restService.test.ts +1844 -139
- 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
|
-
|
|
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;
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
484
|
-
|
|
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
|
-
|
|
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
|
-
|
|
503
|
+
status: 200,
|
|
504
|
+
headers: {},
|
|
505
|
+
data: { value: 42 }
|
|
491
506
|
});
|
|
492
|
-
const status = await asyncService.getAsyncOperationStatus(
|
|
507
|
+
const status = await asyncService.getAsyncOperationStatus('srv-1');
|
|
493
508
|
expect(status).toBe(AsyncOperationService_1.OperationStatus.COMPLETED);
|
|
494
|
-
const operation = asyncService.getOperation(
|
|
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
|
|
498
|
-
|
|
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
|
-
|
|
515
|
+
status: 200,
|
|
516
|
+
headers: { asyncresult: '500 Internal Server Error' },
|
|
517
|
+
data: {}
|
|
505
518
|
});
|
|
506
|
-
const status = await asyncService.getAsyncOperationStatus(
|
|
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
|
|
524
|
-
|
|
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
|
-
|
|
534
|
+
status: 202,
|
|
535
|
+
headers: {},
|
|
536
|
+
data: {}
|
|
531
537
|
});
|
|
532
|
-
const status = await asyncService.getAsyncOperationStatus(
|
|
533
|
-
expect(status).toBe(AsyncOperationService_1.OperationStatus.
|
|
538
|
+
const status = await asyncService.getAsyncOperationStatus('srv-4');
|
|
539
|
+
expect(status).toBe(AsyncOperationService_1.OperationStatus.RUNNING);
|
|
534
540
|
});
|
|
535
|
-
test('
|
|
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: '
|
|
544
|
+
name: 'LocalProcess'
|
|
539
545
|
});
|
|
540
546
|
asyncService.updateOperationStatus(operationId, AsyncOperationService_1.OperationStatus.RUNNING);
|
|
541
|
-
|
|
542
|
-
|
|
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.
|
|
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:
|
|
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:
|
|
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
|
-
|
|
358
|
-
|
|
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
|
-
|
|
367
|
-
|
|
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
|
-
|
|
380
|
-
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restService.test.d.ts","sourceRoot":"","sources":["../../src/tests/restService.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"restService.test.d.ts","sourceRoot":"","sources":["../../src/tests/restService.test.ts"],"names":[],"mappings":""}
|