@tellescope/sdk 1.245.0 → 1.246.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.
- package/lib/cjs/tests/api_tests/beluga_pharmacy_mappings.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/beluga_pharmacy_mappings.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/beluga_pharmacy_mappings.test.js +357 -0
- package/lib/cjs/tests/api_tests/beluga_pharmacy_mappings.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/calendar_event_limits.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/calendar_event_limits.test.js +163 -0
- package/lib/cjs/tests/api_tests/calendar_event_limits.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.js +268 -0
- package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/time_tracks.test.d.ts +20 -0
- package/lib/cjs/tests/api_tests/time_tracks.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/time_tracks.test.js +692 -20
- package/lib/cjs/tests/api_tests/time_tracks.test.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +137 -118
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/tests/api_tests/beluga_pharmacy_mappings.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/beluga_pharmacy_mappings.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/beluga_pharmacy_mappings.test.js +353 -0
- package/lib/esm/tests/api_tests/beluga_pharmacy_mappings.test.js.map +1 -0
- package/lib/esm/tests/api_tests/calendar_event_limits.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/calendar_event_limits.test.js +163 -0
- package/lib/esm/tests/api_tests/calendar_event_limits.test.js.map +1 -1
- package/lib/esm/tests/api_tests/organization_settings_duplicates.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/organization_settings_duplicates.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/organization_settings_duplicates.test.js +264 -0
- package/lib/esm/tests/api_tests/organization_settings_duplicates.test.js.map +1 -0
- package/lib/esm/tests/api_tests/time_tracks.test.d.ts +20 -0
- package/lib/esm/tests/api_tests/time_tracks.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/time_tracks.test.js +687 -20
- package/lib/esm/tests/api_tests/time_tracks.test.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +138 -119
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/tests/api_tests/beluga_pharmacy_mappings.test.ts +351 -0
- package/src/tests/api_tests/calendar_event_limits.test.ts +195 -0
- package/src/tests/api_tests/time_tracks.test.ts +542 -16
- package/src/tests/tests.ts +10 -3
- package/test_generated.pdf +0 -0
|
@@ -45,10 +45,31 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
45
45
|
};
|
|
46
46
|
require('source-map-support').install();
|
|
47
47
|
import { Session } from "../../sdk";
|
|
48
|
-
import { assert, log_header } from "@tellescope/testing";
|
|
48
|
+
import { assert, log_header, wait } from "@tellescope/testing";
|
|
49
49
|
import { setup_tests } from "../setup";
|
|
50
50
|
var log = console.log;
|
|
51
51
|
var host = process.env.REACT_APP_TELLESCOPE_API_URL || 'http://localhost:8080';
|
|
52
|
+
// Helper to assert that an async function throws an error
|
|
53
|
+
var assert_throws = function (fn, description) { return __awaiter(void 0, void 0, void 0, function () {
|
|
54
|
+
var e_1;
|
|
55
|
+
return __generator(this, function (_a) {
|
|
56
|
+
switch (_a.label) {
|
|
57
|
+
case 0:
|
|
58
|
+
_a.trys.push([0, 2, , 3]);
|
|
59
|
+
return [4 /*yield*/, fn()];
|
|
60
|
+
case 1:
|
|
61
|
+
_a.sent();
|
|
62
|
+
assert(false, "".concat(description, " - expected error but succeeded"));
|
|
63
|
+
return [3 /*break*/, 3];
|
|
64
|
+
case 2:
|
|
65
|
+
e_1 = _a.sent();
|
|
66
|
+
// SDK parseError returns the response body { message, info } for 4xx errors
|
|
67
|
+
assert((e_1 === null || e_1 === void 0 ? void 0 : e_1.code) === 400 || (e_1 === null || e_1 === void 0 ? void 0 : e_1.statusCode) === 400 || typeof (e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === 'string', "".concat(description, " - expected error, got: ").concat(JSON.stringify(e_1)));
|
|
68
|
+
return [3 /*break*/, 3];
|
|
69
|
+
case 3: return [2 /*return*/];
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}); };
|
|
52
73
|
// Unit tests for calculateTimeTrackDuration
|
|
53
74
|
var test_calculateTimeTrackDuration = function () {
|
|
54
75
|
log_header("calculateTimeTrackDuration Unit Tests");
|
|
@@ -98,13 +119,13 @@ var test_calculateTimeTrackDuration = function () {
|
|
|
98
119
|
{ type: 'pause', timestamp: new Date('2024-01-01T12:05:00Z') }, // 5 min
|
|
99
120
|
]);
|
|
100
121
|
assert(test7 === 2700000, "Three intervals (10+30+5 min) should be 2700000 ms, got ".concat(test7));
|
|
101
|
-
log("
|
|
122
|
+
log("All calculateTimeTrackDuration unit tests passed");
|
|
102
123
|
};
|
|
103
124
|
// API tests for time_tracks CRUD operations
|
|
104
125
|
export var time_tracks_tests = function (_a) {
|
|
105
126
|
var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
|
|
106
127
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
107
|
-
var userId, createdTimeTrackId, enduserId, timeTrack_1, fetchedTimeTrack, allTimeTracks, enduser, linkedTimeTrack_1, pauseTime, pausedTimeTrack, resumeTime, resumedTimeTrack, closedAt, closedTimeTrack, finalTimeTrack, updatedTimeTrack, allUserTimeTracks, activeTimeTracks, nonAdminTimeTracks, hasOtherUserTimeTrack, deletedCheck, stillExists,
|
|
128
|
+
var userId, createdTimeTrackId, enduserId, timeTrack_1, fetchedTimeTrack, allTimeTracks, enduser, linkedTimeTrack_1, pauseTime, pausedTimeTrack, resumeTime, resumedTimeTrack, closedAt, closedTimeTrack, finalTimeTrack, updatedTimeTrack, allUserTimeTracks, activeTimeTracks, nonAdminTimeTracks, hasOtherUserTimeTrack, deletedCheck, stillExists, e_2, e_3;
|
|
108
129
|
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
109
130
|
return __generator(this, function (_p) {
|
|
110
131
|
switch (_p.label) {
|
|
@@ -129,7 +150,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
129
150
|
assert(((_d = timeTrack_1.timestamps) === null || _d === void 0 ? void 0 : _d[0].type) === 'start', "First timestamp should be 'start', got ".concat((_e = timeTrack_1.timestamps) === null || _e === void 0 ? void 0 : _e[0].type));
|
|
130
151
|
assert(!timeTrack_1.closedAt, "closedAt should not be set initially");
|
|
131
152
|
assert(!timeTrack_1.totalDurationInMS, "totalDurationInMS should not be set initially");
|
|
132
|
-
log("
|
|
153
|
+
log("Time track created with auto-set userId and initial timestamp");
|
|
133
154
|
// Test 2: Read the time track
|
|
134
155
|
log("Reading time track...");
|
|
135
156
|
return [4 /*yield*/, sdk.api.time_tracks.getOne(timeTrack_1.id)];
|
|
@@ -137,7 +158,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
137
158
|
fetchedTimeTrack = _p.sent();
|
|
138
159
|
assert(fetchedTimeTrack.id === timeTrack_1.id, "Fetched time track should have same id");
|
|
139
160
|
assert(fetchedTimeTrack.title === "Test Time Track", "Fetched title should match");
|
|
140
|
-
log("
|
|
161
|
+
log("Time track retrieved successfully");
|
|
141
162
|
// Test 3: Get all time tracks for current user
|
|
142
163
|
log("Getting all time tracks for current user...");
|
|
143
164
|
return [4 /*yield*/, sdk.api.time_tracks.getSome({ filter: { userId: userId } })];
|
|
@@ -145,7 +166,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
145
166
|
allTimeTracks = _p.sent();
|
|
146
167
|
assert(allTimeTracks.length >= 1, "Should have at least 1 time track, got ".concat(allTimeTracks.length));
|
|
147
168
|
assert(!!allTimeTracks.find(function (t) { return t.id === timeTrack_1.id; }), "Should find our created time track");
|
|
148
|
-
log("
|
|
169
|
+
log("Retrieved all time tracks for user");
|
|
149
170
|
// Test 4: Create enduser and link time track
|
|
150
171
|
log("Creating enduser for time track linkage...");
|
|
151
172
|
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
@@ -156,7 +177,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
156
177
|
case 5:
|
|
157
178
|
enduser = _p.sent();
|
|
158
179
|
enduserId = enduser.id;
|
|
159
|
-
log("
|
|
180
|
+
log("Enduser created");
|
|
160
181
|
// Test 5: Create time track with enduserId
|
|
161
182
|
log("Creating time track linked to enduser...");
|
|
162
183
|
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
@@ -166,7 +187,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
166
187
|
case 6:
|
|
167
188
|
linkedTimeTrack_1 = _p.sent();
|
|
168
189
|
assert(linkedTimeTrack_1.enduserId === enduser.id, "enduserId should be set to ".concat(enduser.id, ", got ").concat(linkedTimeTrack_1.enduserId));
|
|
169
|
-
log("
|
|
190
|
+
log("Time track linked to enduser");
|
|
170
191
|
// Test 6: Update time track - add pause timestamp
|
|
171
192
|
log("Adding pause timestamp...");
|
|
172
193
|
pauseTime = new Date();
|
|
@@ -179,7 +200,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
179
200
|
pausedTimeTrack = _p.sent();
|
|
180
201
|
assert(((_f = pausedTimeTrack.timestamps) === null || _f === void 0 ? void 0 : _f.length) === 2, "Should have 2 timestamps after pause, got ".concat((_g = pausedTimeTrack.timestamps) === null || _g === void 0 ? void 0 : _g.length));
|
|
181
202
|
assert(((_h = pausedTimeTrack.timestamps) === null || _h === void 0 ? void 0 : _h[1].type) === 'pause', "Second timestamp should be 'pause', got ".concat((_j = pausedTimeTrack.timestamps) === null || _j === void 0 ? void 0 : _j[1].type));
|
|
182
|
-
log("
|
|
203
|
+
log("Pause timestamp added");
|
|
183
204
|
// Test 7: Update time track - add resume timestamp
|
|
184
205
|
log("Adding resume timestamp...");
|
|
185
206
|
resumeTime = new Date();
|
|
@@ -192,7 +213,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
192
213
|
resumedTimeTrack = _p.sent();
|
|
193
214
|
assert(((_k = resumedTimeTrack.timestamps) === null || _k === void 0 ? void 0 : _k.length) === 3, "Should have 3 timestamps after resume, got ".concat((_l = resumedTimeTrack.timestamps) === null || _l === void 0 ? void 0 : _l.length));
|
|
194
215
|
assert(((_m = resumedTimeTrack.timestamps) === null || _m === void 0 ? void 0 : _m[2].type) === 'resume', "Third timestamp should be 'resume', got ".concat((_o = resumedTimeTrack.timestamps) === null || _o === void 0 ? void 0 : _o[2].type));
|
|
195
|
-
log("
|
|
216
|
+
log("Resume timestamp added");
|
|
196
217
|
// Test 8: Close time track and verify auto-calculation
|
|
197
218
|
log("Closing time track with closedAt...");
|
|
198
219
|
closedAt = new Date();
|
|
@@ -216,7 +237,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
216
237
|
assert(!!finalTimeTrack.closedAt, "closedAt should be set");
|
|
217
238
|
assert(typeof finalTimeTrack.totalDurationInMS === 'number', "totalDurationInMS should be a number, got ".concat(typeof finalTimeTrack.totalDurationInMS));
|
|
218
239
|
assert(finalTimeTrack.totalDurationInMS > 0, "totalDurationInMS should be > 0, got ".concat(finalTimeTrack.totalDurationInMS));
|
|
219
|
-
log("
|
|
240
|
+
log("Time track closed with auto-calculated duration: ".concat(finalTimeTrack.totalDurationInMS, " ms"));
|
|
220
241
|
// Test 9: Update title
|
|
221
242
|
log("Updating time track title...");
|
|
222
243
|
return [4 /*yield*/, sdk.api.time_tracks.updateOne(timeTrack_1.id, {
|
|
@@ -225,7 +246,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
225
246
|
case 12:
|
|
226
247
|
updatedTimeTrack = _p.sent();
|
|
227
248
|
assert(updatedTimeTrack.title === "Updated Time Track Title", "Title should be updated");
|
|
228
|
-
log("
|
|
249
|
+
log("Time track title updated");
|
|
229
250
|
// Test 10: Filter by closedAt (get active time tracks)
|
|
230
251
|
log("Filtering for active time tracks (no closedAt)...");
|
|
231
252
|
return [4 /*yield*/, sdk.api.time_tracks.getSome({
|
|
@@ -236,7 +257,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
236
257
|
activeTimeTracks = allUserTimeTracks.filter(function (t) { return !t.closedAt; });
|
|
237
258
|
assert(!activeTimeTracks.find(function (t) { return t.id === timeTrack_1.id; }), "Closed time track should not appear in active filter");
|
|
238
259
|
assert(!!activeTimeTracks.find(function (t) { return t.id === linkedTimeTrack_1.id; }), "Unclosed time track should appear in active filter");
|
|
239
|
-
log("
|
|
260
|
+
log("Active time tracks filtered correctly");
|
|
240
261
|
// Test 11: Access control - non-admin user should only see their own time tracks
|
|
241
262
|
log("Testing access control with non-admin user...");
|
|
242
263
|
return [4 /*yield*/, sdkNonAdmin.api.time_tracks.getSome({})];
|
|
@@ -244,7 +265,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
244
265
|
nonAdminTimeTracks = _p.sent();
|
|
245
266
|
hasOtherUserTimeTrack = nonAdminTimeTracks.find(function (t) { return t.userId !== sdkNonAdmin.userInfo.id; });
|
|
246
267
|
assert(!hasOtherUserTimeTrack, "Non-admin user should not see other users' time tracks");
|
|
247
|
-
log("
|
|
268
|
+
log("Access control working correctly");
|
|
248
269
|
// Test 12: Delete time tracks
|
|
249
270
|
log("Deleting time tracks...");
|
|
250
271
|
return [4 /*yield*/, sdk.api.time_tracks.deleteOne(timeTrack_1.id)];
|
|
@@ -258,8 +279,8 @@ export var time_tracks_tests = function (_a) {
|
|
|
258
279
|
deletedCheck = _p.sent();
|
|
259
280
|
stillExists = deletedCheck.filter(function (t) { return t.id === timeTrack_1.id || t.id === linkedTimeTrack_1.id; });
|
|
260
281
|
assert(stillExists.length === 0, "Time tracks should be deleted");
|
|
261
|
-
log("
|
|
262
|
-
log("
|
|
282
|
+
log("Time tracks deleted successfully");
|
|
283
|
+
log("All time tracks API tests passed!");
|
|
263
284
|
return [3 /*break*/, 27];
|
|
264
285
|
case 18:
|
|
265
286
|
if (!createdTimeTrackId) return [3 /*break*/, 22];
|
|
@@ -271,7 +292,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
271
292
|
_p.sent();
|
|
272
293
|
return [3 /*break*/, 22];
|
|
273
294
|
case 21:
|
|
274
|
-
|
|
295
|
+
e_2 = _p.sent();
|
|
275
296
|
return [3 /*break*/, 22];
|
|
276
297
|
case 22:
|
|
277
298
|
if (!enduserId) return [3 /*break*/, 26];
|
|
@@ -283,7 +304,7 @@ export var time_tracks_tests = function (_a) {
|
|
|
283
304
|
_p.sent();
|
|
284
305
|
return [3 /*break*/, 26];
|
|
285
306
|
case 25:
|
|
286
|
-
|
|
307
|
+
e_3 = _p.sent();
|
|
287
308
|
return [3 /*break*/, 26];
|
|
288
309
|
case 26: return [7 /*endfinally*/];
|
|
289
310
|
case 27: return [2 /*return*/];
|
|
@@ -291,6 +312,637 @@ export var time_tracks_tests = function (_a) {
|
|
|
291
312
|
});
|
|
292
313
|
});
|
|
293
314
|
};
|
|
315
|
+
// ============================================================
|
|
316
|
+
// Group A: Historical Time Track Creation
|
|
317
|
+
// ============================================================
|
|
318
|
+
export var time_tracks_historical_tests = function (_a) {
|
|
319
|
+
var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
|
|
320
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
321
|
+
var trackIds, now_1, oneHourAgo, twoHoursAgo_1, historical_1, fetched, _i, trackIds_1, id, e_4;
|
|
322
|
+
var _b;
|
|
323
|
+
return __generator(this, function (_c) {
|
|
324
|
+
switch (_c.label) {
|
|
325
|
+
case 0:
|
|
326
|
+
log_header("Time Tracks - Historical Creation Tests");
|
|
327
|
+
trackIds = [];
|
|
328
|
+
_c.label = 1;
|
|
329
|
+
case 1:
|
|
330
|
+
_c.trys.push([1, , 7, 14]);
|
|
331
|
+
now_1 = new Date();
|
|
332
|
+
oneHourAgo = new Date(now_1.getTime() - 3600000);
|
|
333
|
+
twoHoursAgo_1 = new Date(now_1.getTime() - 7200000);
|
|
334
|
+
// Test A1: Create historical time track with all required fields
|
|
335
|
+
log("A1: Creating historical time track with all required fields...");
|
|
336
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
337
|
+
title: "Historical Entry",
|
|
338
|
+
isHistorical: true,
|
|
339
|
+
closedAt: now_1,
|
|
340
|
+
lockedAt: now_1,
|
|
341
|
+
lockedByUserId: sdk.userInfo.id,
|
|
342
|
+
totalDurationInMS: 3600000,
|
|
343
|
+
timestamps: [
|
|
344
|
+
{ type: 'start', timestamp: twoHoursAgo_1 },
|
|
345
|
+
{ type: 'pause', timestamp: oneHourAgo },
|
|
346
|
+
],
|
|
347
|
+
})];
|
|
348
|
+
case 2:
|
|
349
|
+
historical_1 = _c.sent();
|
|
350
|
+
trackIds.push(historical_1.id);
|
|
351
|
+
assert(historical_1.isHistorical === true, "isHistorical should be true");
|
|
352
|
+
assert(!!historical_1.closedAt, "closedAt should be set");
|
|
353
|
+
assert(!!historical_1.lockedAt, "lockedAt should be set");
|
|
354
|
+
assert(historical_1.lockedByUserId === sdk.userInfo.id, "lockedByUserId should match");
|
|
355
|
+
assert(historical_1.totalDurationInMS === 3600000, "totalDurationInMS should be 3600000, got ".concat(historical_1.totalDurationInMS));
|
|
356
|
+
assert(((_b = historical_1.timestamps) === null || _b === void 0 ? void 0 : _b.length) === 2, "timestamps should have 2 entries");
|
|
357
|
+
log("A1: Historical time track created with all fields persisted");
|
|
358
|
+
// Test A2: Create historical without closedAt - expect 400
|
|
359
|
+
log("A2: Creating historical without closedAt (should fail)...");
|
|
360
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.createOne({
|
|
361
|
+
title: "Missing ClosedAt",
|
|
362
|
+
isHistorical: true,
|
|
363
|
+
lockedAt: now_1,
|
|
364
|
+
lockedByUserId: sdk.userInfo.id,
|
|
365
|
+
totalDurationInMS: 3600000,
|
|
366
|
+
timestamps: [{ type: 'start', timestamp: twoHoursAgo_1 }],
|
|
367
|
+
}); }, "A2: Historical without closedAt")];
|
|
368
|
+
case 3:
|
|
369
|
+
_c.sent();
|
|
370
|
+
log("A2: Correctly rejected historical without closedAt");
|
|
371
|
+
// Test A3: Create historical without lockedAt - expect 400
|
|
372
|
+
log("A3: Creating historical without lockedAt (should fail)...");
|
|
373
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.createOne({
|
|
374
|
+
title: "Missing LockedAt",
|
|
375
|
+
isHistorical: true,
|
|
376
|
+
closedAt: now_1,
|
|
377
|
+
lockedByUserId: sdk.userInfo.id,
|
|
378
|
+
totalDurationInMS: 3600000,
|
|
379
|
+
timestamps: [{ type: 'start', timestamp: twoHoursAgo_1 }],
|
|
380
|
+
}); }, "A3: Historical without lockedAt")];
|
|
381
|
+
case 4:
|
|
382
|
+
_c.sent();
|
|
383
|
+
log("A3: Correctly rejected historical without lockedAt");
|
|
384
|
+
// Test A4: Verify isHistorical cannot be updated (updatesDisabled)
|
|
385
|
+
log("A4: Attempting to update isHistorical (should be rejected)...");
|
|
386
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(historical_1.id, {
|
|
387
|
+
isHistorical: false,
|
|
388
|
+
}); }, "A4: isHistorical update should be rejected")
|
|
389
|
+
// Confirm it's still true
|
|
390
|
+
];
|
|
391
|
+
case 5:
|
|
392
|
+
_c.sent();
|
|
393
|
+
return [4 /*yield*/, sdk.api.time_tracks.getOne(historical_1.id)];
|
|
394
|
+
case 6:
|
|
395
|
+
fetched = _c.sent();
|
|
396
|
+
assert(fetched.isHistorical === true, "isHistorical should remain true after rejected update");
|
|
397
|
+
log("A4: isHistorical correctly rejected on update");
|
|
398
|
+
log("All historical creation tests passed!");
|
|
399
|
+
return [3 /*break*/, 14];
|
|
400
|
+
case 7:
|
|
401
|
+
_i = 0, trackIds_1 = trackIds;
|
|
402
|
+
_c.label = 8;
|
|
403
|
+
case 8:
|
|
404
|
+
if (!(_i < trackIds_1.length)) return [3 /*break*/, 13];
|
|
405
|
+
id = trackIds_1[_i];
|
|
406
|
+
_c.label = 9;
|
|
407
|
+
case 9:
|
|
408
|
+
_c.trys.push([9, 11, , 12]);
|
|
409
|
+
return [4 /*yield*/, sdk.api.time_tracks.deleteOne(id)];
|
|
410
|
+
case 10:
|
|
411
|
+
_c.sent();
|
|
412
|
+
return [3 /*break*/, 12];
|
|
413
|
+
case 11:
|
|
414
|
+
e_4 = _c.sent();
|
|
415
|
+
return [3 /*break*/, 12];
|
|
416
|
+
case 12:
|
|
417
|
+
_i++;
|
|
418
|
+
return [3 /*break*/, 8];
|
|
419
|
+
case 13: return [7 /*endfinally*/];
|
|
420
|
+
case 14: return [2 /*return*/];
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
};
|
|
425
|
+
// ============================================================
|
|
426
|
+
// Group B: Correction Flow
|
|
427
|
+
// ============================================================
|
|
428
|
+
export var time_tracks_correction_tests = function (_a) {
|
|
429
|
+
var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
|
|
430
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
431
|
+
var trackIds, now, track_1, closedAt, closed_1, originalDuration, correctionTime, correctedTrack_1, track2_1, closed2_1, _i, trackIds_2, id, e_5;
|
|
432
|
+
return __generator(this, function (_b) {
|
|
433
|
+
switch (_b.label) {
|
|
434
|
+
case 0:
|
|
435
|
+
log_header("Time Tracks - Correction Flow Tests");
|
|
436
|
+
trackIds = [];
|
|
437
|
+
_b.label = 1;
|
|
438
|
+
case 1:
|
|
439
|
+
_b.trys.push([1, , 16, 23]);
|
|
440
|
+
now = new Date();
|
|
441
|
+
// Create a real-time track and close it
|
|
442
|
+
log("B0: Creating and closing real-time track...");
|
|
443
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
444
|
+
title: "Track for Correction",
|
|
445
|
+
})];
|
|
446
|
+
case 2:
|
|
447
|
+
track_1 = _b.sent();
|
|
448
|
+
trackIds.push(track_1.id);
|
|
449
|
+
// Add pause
|
|
450
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(track_1.id, {
|
|
451
|
+
timestamps: __spreadArray(__spreadArray([], (track_1.timestamps || []), true), [
|
|
452
|
+
{ type: 'pause', timestamp: new Date() },
|
|
453
|
+
], false)
|
|
454
|
+
}, { replaceObjectFields: true })
|
|
455
|
+
// Close it
|
|
456
|
+
];
|
|
457
|
+
case 3:
|
|
458
|
+
// Add pause
|
|
459
|
+
_b.sent();
|
|
460
|
+
closedAt = new Date();
|
|
461
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(track_1.id, { closedAt: closedAt })
|
|
462
|
+
// Wait for auto-calculated duration
|
|
463
|
+
];
|
|
464
|
+
case 4:
|
|
465
|
+
_b.sent();
|
|
466
|
+
// Wait for auto-calculated duration
|
|
467
|
+
return [4 /*yield*/, wait(undefined, 1500)];
|
|
468
|
+
case 5:
|
|
469
|
+
// Wait for auto-calculated duration
|
|
470
|
+
_b.sent();
|
|
471
|
+
return [4 /*yield*/, sdk.api.time_tracks.getOne(track_1.id)];
|
|
472
|
+
case 6:
|
|
473
|
+
closed_1 = _b.sent();
|
|
474
|
+
assert(!!closed_1.closedAt, "Track should be closed");
|
|
475
|
+
assert(typeof closed_1.totalDurationInMS === 'number', "Should have auto-calculated totalDurationInMS");
|
|
476
|
+
originalDuration = closed_1.totalDurationInMS;
|
|
477
|
+
log("B0: Track closed with auto-calculated duration: ".concat(originalDuration, " ms"));
|
|
478
|
+
// Test B1: Apply correction with all required fields
|
|
479
|
+
log("B1: Applying correction with all required fields...");
|
|
480
|
+
correctionTime = new Date();
|
|
481
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(track_1.id, {
|
|
482
|
+
correctedAt: correctionTime,
|
|
483
|
+
correctedByUserId: sdk.userInfo.id,
|
|
484
|
+
correctionNote: "Forgot to pause during lunch",
|
|
485
|
+
originalTotalDurationInMS: originalDuration,
|
|
486
|
+
totalDurationInMS: originalDuration - 1800000,
|
|
487
|
+
lockedAt: correctionTime,
|
|
488
|
+
lockedByUserId: sdk.userInfo.id,
|
|
489
|
+
})];
|
|
490
|
+
case 7:
|
|
491
|
+
correctedTrack_1 = _b.sent();
|
|
492
|
+
assert(!!correctedTrack_1.correctedAt, "correctedAt should be set");
|
|
493
|
+
assert(correctedTrack_1.correctedByUserId === sdk.userInfo.id, "correctedByUserId should match");
|
|
494
|
+
assert(correctedTrack_1.correctionNote === "Forgot to pause during lunch", "correctionNote should match");
|
|
495
|
+
assert(correctedTrack_1.originalTotalDurationInMS === originalDuration, "originalTotalDurationInMS should preserve old value");
|
|
496
|
+
assert(correctedTrack_1.totalDurationInMS === originalDuration - 1800000, "totalDurationInMS should be corrected value");
|
|
497
|
+
assert(!!correctedTrack_1.lockedAt, "lockedAt should be set");
|
|
498
|
+
log("B1: Correction applied successfully with all fields persisted");
|
|
499
|
+
// Test B2: Correction without originalTotalDurationInMS - expect 400
|
|
500
|
+
log("B2: Correction without originalTotalDurationInMS (should fail)...");
|
|
501
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({ title: "Track for B2" })];
|
|
502
|
+
case 8:
|
|
503
|
+
track2_1 = _b.sent();
|
|
504
|
+
trackIds.push(track2_1.id);
|
|
505
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(track2_1.id, { closedAt: new Date() })];
|
|
506
|
+
case 9:
|
|
507
|
+
_b.sent();
|
|
508
|
+
return [4 /*yield*/, wait(undefined, 1000)];
|
|
509
|
+
case 10:
|
|
510
|
+
_b.sent();
|
|
511
|
+
return [4 /*yield*/, sdk.api.time_tracks.getOne(track2_1.id)];
|
|
512
|
+
case 11:
|
|
513
|
+
closed2_1 = _b.sent();
|
|
514
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(track2_1.id, {
|
|
515
|
+
correctedAt: new Date(),
|
|
516
|
+
totalDurationInMS: 1000,
|
|
517
|
+
lockedAt: new Date(),
|
|
518
|
+
lockedByUserId: sdk.userInfo.id,
|
|
519
|
+
}); }, "B2: Correction without originalTotalDurationInMS")];
|
|
520
|
+
case 12:
|
|
521
|
+
_b.sent();
|
|
522
|
+
log("B2: Correctly rejected correction without originalTotalDurationInMS");
|
|
523
|
+
// Test B3: Correction without lockedAt - expect 400
|
|
524
|
+
log("B3: Correction without lockedAt (should fail)...");
|
|
525
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(track2_1.id, {
|
|
526
|
+
correctedAt: new Date(),
|
|
527
|
+
originalTotalDurationInMS: closed2_1.totalDurationInMS || 0,
|
|
528
|
+
totalDurationInMS: 1000,
|
|
529
|
+
lockedByUserId: sdk.userInfo.id,
|
|
530
|
+
}); }, "B3: Correction without lockedAt")];
|
|
531
|
+
case 13:
|
|
532
|
+
_b.sent();
|
|
533
|
+
log("B3: Correctly rejected correction without lockedAt");
|
|
534
|
+
// Test B4: After lock, attempt to update title - expect 400
|
|
535
|
+
log("B4: Updating title on locked track (should fail)...");
|
|
536
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(track_1.id, {
|
|
537
|
+
title: "Should Not Work",
|
|
538
|
+
}); }, "B4: Title update on locked track")];
|
|
539
|
+
case 14:
|
|
540
|
+
_b.sent();
|
|
541
|
+
log("B4: Correctly rejected title update on locked track");
|
|
542
|
+
// Test B5: After lock, attempt second correction - expect 400
|
|
543
|
+
log("B5: Second correction on locked track (should fail)...");
|
|
544
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(track_1.id, {
|
|
545
|
+
correctedAt: new Date(),
|
|
546
|
+
originalTotalDurationInMS: correctedTrack_1.totalDurationInMS,
|
|
547
|
+
totalDurationInMS: 500,
|
|
548
|
+
lockedAt: new Date(),
|
|
549
|
+
lockedByUserId: sdk.userInfo.id,
|
|
550
|
+
}); }, "B5: Second correction on locked track")];
|
|
551
|
+
case 15:
|
|
552
|
+
_b.sent();
|
|
553
|
+
log("B5: Correctly rejected second correction on locked track");
|
|
554
|
+
log("All correction flow tests passed!");
|
|
555
|
+
return [3 /*break*/, 23];
|
|
556
|
+
case 16:
|
|
557
|
+
_i = 0, trackIds_2 = trackIds;
|
|
558
|
+
_b.label = 17;
|
|
559
|
+
case 17:
|
|
560
|
+
if (!(_i < trackIds_2.length)) return [3 /*break*/, 22];
|
|
561
|
+
id = trackIds_2[_i];
|
|
562
|
+
_b.label = 18;
|
|
563
|
+
case 18:
|
|
564
|
+
_b.trys.push([18, 20, , 21]);
|
|
565
|
+
return [4 /*yield*/, sdk.api.time_tracks.deleteOne(id)];
|
|
566
|
+
case 19:
|
|
567
|
+
_b.sent();
|
|
568
|
+
return [3 /*break*/, 21];
|
|
569
|
+
case 20:
|
|
570
|
+
e_5 = _b.sent();
|
|
571
|
+
return [3 /*break*/, 21];
|
|
572
|
+
case 21:
|
|
573
|
+
_i++;
|
|
574
|
+
return [3 /*break*/, 17];
|
|
575
|
+
case 22: return [7 /*endfinally*/];
|
|
576
|
+
case 23: return [2 /*return*/];
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
});
|
|
580
|
+
};
|
|
581
|
+
// ============================================================
|
|
582
|
+
// Group C: Review Flow
|
|
583
|
+
// ============================================================
|
|
584
|
+
export var time_tracks_review_tests = function (_a) {
|
|
585
|
+
var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
|
|
586
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
587
|
+
var trackIds, now, oneHourAgo, twoHoursAgo, historical, reviewTime, reviewed, historical2_1, updatedReview, historical3, rejected, _i, trackIds_3, id, e_6;
|
|
588
|
+
return __generator(this, function (_b) {
|
|
589
|
+
switch (_b.label) {
|
|
590
|
+
case 0:
|
|
591
|
+
log_header("Time Tracks - Review Flow Tests");
|
|
592
|
+
trackIds = [];
|
|
593
|
+
_b.label = 1;
|
|
594
|
+
case 1:
|
|
595
|
+
_b.trys.push([1, , 9, 16]);
|
|
596
|
+
now = new Date();
|
|
597
|
+
oneHourAgo = new Date(now.getTime() - 3600000);
|
|
598
|
+
twoHoursAgo = new Date(now.getTime() - 7200000);
|
|
599
|
+
// Create a historical track for review testing
|
|
600
|
+
log("C0: Creating historical track for review tests...");
|
|
601
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
602
|
+
title: "Track for Review",
|
|
603
|
+
isHistorical: true,
|
|
604
|
+
closedAt: now,
|
|
605
|
+
lockedAt: now,
|
|
606
|
+
lockedByUserId: sdk.userInfo.id,
|
|
607
|
+
totalDurationInMS: 3600000,
|
|
608
|
+
timestamps: [
|
|
609
|
+
{ type: 'start', timestamp: twoHoursAgo },
|
|
610
|
+
{ type: 'pause', timestamp: oneHourAgo },
|
|
611
|
+
],
|
|
612
|
+
})];
|
|
613
|
+
case 2:
|
|
614
|
+
historical = _b.sent();
|
|
615
|
+
trackIds.push(historical.id);
|
|
616
|
+
log("C0: Historical track created");
|
|
617
|
+
// Test C1: Review by different user (approval)
|
|
618
|
+
log("C1: Review by different user (approval)...");
|
|
619
|
+
reviewTime = new Date();
|
|
620
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(historical.id, {
|
|
621
|
+
reviewedAt: reviewTime,
|
|
622
|
+
reviewedByUserId: sdkNonAdmin.userInfo.id,
|
|
623
|
+
reviewApproved: true,
|
|
624
|
+
})];
|
|
625
|
+
case 3:
|
|
626
|
+
reviewed = _b.sent();
|
|
627
|
+
assert(!!reviewed.reviewedAt, "reviewedAt should be set");
|
|
628
|
+
assert(reviewed.reviewedByUserId === sdkNonAdmin.userInfo.id, "reviewedByUserId should match non-admin");
|
|
629
|
+
assert(reviewed.reviewApproved === true, "reviewApproved should be true");
|
|
630
|
+
log("C1: Review approved successfully by different user");
|
|
631
|
+
// Test C2: Self-review (owner reviews own track) - expect 400
|
|
632
|
+
log("C2: Self-review (should fail)...");
|
|
633
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
634
|
+
title: "Track for Self-Review",
|
|
635
|
+
isHistorical: true,
|
|
636
|
+
closedAt: now,
|
|
637
|
+
lockedAt: now,
|
|
638
|
+
lockedByUserId: sdk.userInfo.id,
|
|
639
|
+
totalDurationInMS: 3600000,
|
|
640
|
+
timestamps: [
|
|
641
|
+
{ type: 'start', timestamp: twoHoursAgo },
|
|
642
|
+
{ type: 'pause', timestamp: oneHourAgo },
|
|
643
|
+
],
|
|
644
|
+
})];
|
|
645
|
+
case 4:
|
|
646
|
+
historical2_1 = _b.sent();
|
|
647
|
+
trackIds.push(historical2_1.id);
|
|
648
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(historical2_1.id, {
|
|
649
|
+
reviewedAt: new Date(),
|
|
650
|
+
reviewedByUserId: sdk.userInfo.id,
|
|
651
|
+
reviewApproved: true,
|
|
652
|
+
}); }, "C2: Self-review")];
|
|
653
|
+
case 5:
|
|
654
|
+
_b.sent();
|
|
655
|
+
log("C2: Correctly rejected self-review");
|
|
656
|
+
// Test C3: Review fields updatable even after lock
|
|
657
|
+
log("C3: Review fields updatable after lock...");
|
|
658
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(historical.id, {
|
|
659
|
+
reviewedAt: new Date(),
|
|
660
|
+
reviewedByUserId: sdkNonAdmin.userInfo.id,
|
|
661
|
+
reviewApproved: false,
|
|
662
|
+
reviewNote: "Hours seem too high, please double-check",
|
|
663
|
+
})];
|
|
664
|
+
case 6:
|
|
665
|
+
updatedReview = _b.sent();
|
|
666
|
+
assert(updatedReview.reviewApproved === false, "reviewApproved should be updated to false");
|
|
667
|
+
assert(updatedReview.reviewNote === "Hours seem too high, please double-check", "reviewNote should be set");
|
|
668
|
+
log("C3: Review fields correctly updatable on locked track");
|
|
669
|
+
// Test C4: Rejection flow with reviewNote
|
|
670
|
+
log("C4: Rejection flow with reviewNote...");
|
|
671
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
672
|
+
title: "Track for Rejection",
|
|
673
|
+
isHistorical: true,
|
|
674
|
+
closedAt: now,
|
|
675
|
+
lockedAt: now,
|
|
676
|
+
lockedByUserId: sdk.userInfo.id,
|
|
677
|
+
totalDurationInMS: 1800000,
|
|
678
|
+
timestamps: [
|
|
679
|
+
{ type: 'start', timestamp: twoHoursAgo },
|
|
680
|
+
{ type: 'pause', timestamp: oneHourAgo },
|
|
681
|
+
],
|
|
682
|
+
})];
|
|
683
|
+
case 7:
|
|
684
|
+
historical3 = _b.sent();
|
|
685
|
+
trackIds.push(historical3.id);
|
|
686
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(historical3.id, {
|
|
687
|
+
reviewedAt: new Date(),
|
|
688
|
+
reviewedByUserId: sdkNonAdmin.userInfo.id,
|
|
689
|
+
reviewApproved: false,
|
|
690
|
+
reviewNote: "Rejected - timestamps don't match claimed duration",
|
|
691
|
+
})];
|
|
692
|
+
case 8:
|
|
693
|
+
rejected = _b.sent();
|
|
694
|
+
assert(rejected.reviewApproved === false, "reviewApproved should be false");
|
|
695
|
+
assert(rejected.reviewNote === "Rejected - timestamps don't match claimed duration", "reviewNote should match");
|
|
696
|
+
log("C4: Rejection flow completed successfully");
|
|
697
|
+
log("All review flow tests passed!");
|
|
698
|
+
return [3 /*break*/, 16];
|
|
699
|
+
case 9:
|
|
700
|
+
_i = 0, trackIds_3 = trackIds;
|
|
701
|
+
_b.label = 10;
|
|
702
|
+
case 10:
|
|
703
|
+
if (!(_i < trackIds_3.length)) return [3 /*break*/, 15];
|
|
704
|
+
id = trackIds_3[_i];
|
|
705
|
+
_b.label = 11;
|
|
706
|
+
case 11:
|
|
707
|
+
_b.trys.push([11, 13, , 14]);
|
|
708
|
+
return [4 /*yield*/, sdk.api.time_tracks.deleteOne(id)];
|
|
709
|
+
case 12:
|
|
710
|
+
_b.sent();
|
|
711
|
+
return [3 /*break*/, 14];
|
|
712
|
+
case 13:
|
|
713
|
+
e_6 = _b.sent();
|
|
714
|
+
return [3 /*break*/, 14];
|
|
715
|
+
case 14:
|
|
716
|
+
_i++;
|
|
717
|
+
return [3 /*break*/, 10];
|
|
718
|
+
case 15: return [7 /*endfinally*/];
|
|
719
|
+
case 16: return [2 /*return*/];
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
});
|
|
723
|
+
};
|
|
724
|
+
// ============================================================
|
|
725
|
+
// Group D: Lock Enforcement
|
|
726
|
+
// ============================================================
|
|
727
|
+
export var time_tracks_lock_tests = function (_a) {
|
|
728
|
+
var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
|
|
729
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
730
|
+
var trackIds, now, oneHourAgo, twoHoursAgo, locked_1, reviewed, _i, trackIds_4, id, e_7;
|
|
731
|
+
return __generator(this, function (_b) {
|
|
732
|
+
switch (_b.label) {
|
|
733
|
+
case 0:
|
|
734
|
+
log_header("Time Tracks - Lock Enforcement Tests");
|
|
735
|
+
trackIds = [];
|
|
736
|
+
_b.label = 1;
|
|
737
|
+
case 1:
|
|
738
|
+
_b.trys.push([1, , 9, 16]);
|
|
739
|
+
now = new Date();
|
|
740
|
+
oneHourAgo = new Date(now.getTime() - 3600000);
|
|
741
|
+
twoHoursAgo = new Date(now.getTime() - 7200000);
|
|
742
|
+
// Create a locked historical track
|
|
743
|
+
log("D0: Creating locked historical track...");
|
|
744
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
745
|
+
title: "Locked Track",
|
|
746
|
+
isHistorical: true,
|
|
747
|
+
closedAt: now,
|
|
748
|
+
lockedAt: now,
|
|
749
|
+
lockedByUserId: sdk.userInfo.id,
|
|
750
|
+
totalDurationInMS: 3600000,
|
|
751
|
+
timestamps: [
|
|
752
|
+
{ type: 'start', timestamp: twoHoursAgo },
|
|
753
|
+
{ type: 'pause', timestamp: oneHourAgo },
|
|
754
|
+
],
|
|
755
|
+
})];
|
|
756
|
+
case 2:
|
|
757
|
+
locked_1 = _b.sent();
|
|
758
|
+
trackIds.push(locked_1.id);
|
|
759
|
+
log("D0: Locked track created");
|
|
760
|
+
// Test D1: Locked track rejects updates to timestamps
|
|
761
|
+
log("D1: Updating timestamps on locked track (should fail)...");
|
|
762
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(locked_1.id, {
|
|
763
|
+
timestamps: [{ type: 'start', timestamp: new Date() }],
|
|
764
|
+
}); }, "D1: timestamps update on locked track")];
|
|
765
|
+
case 3:
|
|
766
|
+
_b.sent();
|
|
767
|
+
log("D1: Correctly rejected timestamps update");
|
|
768
|
+
// Test D2: Locked track rejects updates to closedAt
|
|
769
|
+
log("D2: Updating closedAt on locked track (should fail)...");
|
|
770
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(locked_1.id, {
|
|
771
|
+
closedAt: new Date(),
|
|
772
|
+
}); }, "D2: closedAt update on locked track")];
|
|
773
|
+
case 4:
|
|
774
|
+
_b.sent();
|
|
775
|
+
log("D2: Correctly rejected closedAt update");
|
|
776
|
+
// Test D3: Locked track rejects updates to totalDurationInMS
|
|
777
|
+
log("D3: Updating totalDurationInMS on locked track (should fail)...");
|
|
778
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(locked_1.id, {
|
|
779
|
+
totalDurationInMS: 999,
|
|
780
|
+
}); }, "D3: totalDurationInMS update on locked track")];
|
|
781
|
+
case 5:
|
|
782
|
+
_b.sent();
|
|
783
|
+
log("D3: Correctly rejected totalDurationInMS update");
|
|
784
|
+
// Test D4: Locked track rejects updates to correctedAt
|
|
785
|
+
log("D4: Updating correctedAt on locked track (should fail)...");
|
|
786
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(locked_1.id, {
|
|
787
|
+
correctedAt: new Date(),
|
|
788
|
+
originalTotalDurationInMS: 3600000,
|
|
789
|
+
totalDurationInMS: 1800000,
|
|
790
|
+
lockedAt: new Date(),
|
|
791
|
+
lockedByUserId: sdk.userInfo.id,
|
|
792
|
+
}); }, "D4: correctedAt update on locked track")];
|
|
793
|
+
case 6:
|
|
794
|
+
_b.sent();
|
|
795
|
+
log("D4: Correctly rejected correction on locked track");
|
|
796
|
+
// Test D5: Locked track rejects updates to title
|
|
797
|
+
log("D5: Updating title on locked track (should fail)...");
|
|
798
|
+
return [4 /*yield*/, assert_throws(function () { return sdk.api.time_tracks.updateOne(locked_1.id, {
|
|
799
|
+
title: "Should Not Change",
|
|
800
|
+
}); }, "D5: title update on locked track")];
|
|
801
|
+
case 7:
|
|
802
|
+
_b.sent();
|
|
803
|
+
log("D5: Correctly rejected title update");
|
|
804
|
+
// Test D6: Locked track allows updates to review fields
|
|
805
|
+
log("D6: Updating review fields on locked track (should succeed)...");
|
|
806
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(locked_1.id, {
|
|
807
|
+
reviewedAt: new Date(),
|
|
808
|
+
reviewedByUserId: sdkNonAdmin.userInfo.id,
|
|
809
|
+
reviewApproved: true,
|
|
810
|
+
reviewNote: "Looks good",
|
|
811
|
+
})];
|
|
812
|
+
case 8:
|
|
813
|
+
reviewed = _b.sent();
|
|
814
|
+
assert(reviewed.reviewApproved === true, "reviewApproved should be set");
|
|
815
|
+
assert(reviewed.reviewNote === "Looks good", "reviewNote should be set");
|
|
816
|
+
assert(reviewed.reviewedByUserId === sdkNonAdmin.userInfo.id, "reviewedByUserId should match");
|
|
817
|
+
log("D6: Review fields correctly updatable on locked track");
|
|
818
|
+
log("All lock enforcement tests passed!");
|
|
819
|
+
return [3 /*break*/, 16];
|
|
820
|
+
case 9:
|
|
821
|
+
_i = 0, trackIds_4 = trackIds;
|
|
822
|
+
_b.label = 10;
|
|
823
|
+
case 10:
|
|
824
|
+
if (!(_i < trackIds_4.length)) return [3 /*break*/, 15];
|
|
825
|
+
id = trackIds_4[_i];
|
|
826
|
+
_b.label = 11;
|
|
827
|
+
case 11:
|
|
828
|
+
_b.trys.push([11, 13, , 14]);
|
|
829
|
+
return [4 /*yield*/, sdk.api.time_tracks.deleteOne(id)];
|
|
830
|
+
case 12:
|
|
831
|
+
_b.sent();
|
|
832
|
+
return [3 /*break*/, 14];
|
|
833
|
+
case 13:
|
|
834
|
+
e_7 = _b.sent();
|
|
835
|
+
return [3 /*break*/, 14];
|
|
836
|
+
case 14:
|
|
837
|
+
_i++;
|
|
838
|
+
return [3 /*break*/, 10];
|
|
839
|
+
case 15: return [7 /*endfinally*/];
|
|
840
|
+
case 16: return [2 /*return*/];
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
});
|
|
844
|
+
};
|
|
845
|
+
// ============================================================
|
|
846
|
+
// Group E: Edge Cases
|
|
847
|
+
// ============================================================
|
|
848
|
+
export var time_tracks_edge_case_tests = function (_a) {
|
|
849
|
+
var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
|
|
850
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
851
|
+
var trackIds, track, updated, withPause, track2, closedTrack, originalDuration, corrected, _i, trackIds_5, id, e_8;
|
|
852
|
+
var _b;
|
|
853
|
+
return __generator(this, function (_c) {
|
|
854
|
+
switch (_c.label) {
|
|
855
|
+
case 0:
|
|
856
|
+
log_header("Time Tracks - Edge Case Tests");
|
|
857
|
+
trackIds = [];
|
|
858
|
+
_c.label = 1;
|
|
859
|
+
case 1:
|
|
860
|
+
_c.trys.push([1, , 10, 17]);
|
|
861
|
+
// Test E1: Normal real-time track - lockedAt stays undefined, all fields updatable
|
|
862
|
+
log("E1: Normal real-time track is fully updatable...");
|
|
863
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
864
|
+
title: "Normal Track",
|
|
865
|
+
})];
|
|
866
|
+
case 2:
|
|
867
|
+
track = _c.sent();
|
|
868
|
+
trackIds.push(track.id);
|
|
869
|
+
assert(!track.lockedAt, "lockedAt should be undefined for normal track");
|
|
870
|
+
assert(!track.isHistorical, "isHistorical should be undefined for normal track");
|
|
871
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(track.id, {
|
|
872
|
+
title: "Updated Normal Track",
|
|
873
|
+
})];
|
|
874
|
+
case 3:
|
|
875
|
+
updated = _c.sent();
|
|
876
|
+
assert(updated.title === "Updated Normal Track", "Title should be updatable on unlocked track");
|
|
877
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(track.id, {
|
|
878
|
+
timestamps: __spreadArray(__spreadArray([], (track.timestamps || []), true), [
|
|
879
|
+
{ type: 'pause', timestamp: new Date() },
|
|
880
|
+
], false)
|
|
881
|
+
}, { replaceObjectFields: true })];
|
|
882
|
+
case 4:
|
|
883
|
+
withPause = _c.sent();
|
|
884
|
+
assert(((_b = withPause.timestamps) === null || _b === void 0 ? void 0 : _b.length) === 2, "timestamps should be updatable on unlocked track");
|
|
885
|
+
log("E1: Normal track fully updatable as expected");
|
|
886
|
+
// Test E2: Original totalDurationInMS preserved after correction
|
|
887
|
+
log("E2: Original duration preserved after correction...");
|
|
888
|
+
return [4 /*yield*/, sdk.api.time_tracks.createOne({
|
|
889
|
+
title: "Track for Duration Preservation",
|
|
890
|
+
})];
|
|
891
|
+
case 5:
|
|
892
|
+
track2 = _c.sent();
|
|
893
|
+
trackIds.push(track2.id);
|
|
894
|
+
// Close the track
|
|
895
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(track2.id, { closedAt: new Date() })];
|
|
896
|
+
case 6:
|
|
897
|
+
// Close the track
|
|
898
|
+
_c.sent();
|
|
899
|
+
return [4 /*yield*/, wait(undefined, 1500)];
|
|
900
|
+
case 7:
|
|
901
|
+
_c.sent();
|
|
902
|
+
return [4 /*yield*/, sdk.api.time_tracks.getOne(track2.id)];
|
|
903
|
+
case 8:
|
|
904
|
+
closedTrack = _c.sent();
|
|
905
|
+
originalDuration = closedTrack.totalDurationInMS;
|
|
906
|
+
return [4 /*yield*/, sdk.api.time_tracks.updateOne(track2.id, {
|
|
907
|
+
correctedAt: new Date(),
|
|
908
|
+
correctedByUserId: sdk.userInfo.id,
|
|
909
|
+
originalTotalDurationInMS: originalDuration,
|
|
910
|
+
totalDurationInMS: 5000,
|
|
911
|
+
lockedAt: new Date(),
|
|
912
|
+
lockedByUserId: sdk.userInfo.id,
|
|
913
|
+
})];
|
|
914
|
+
case 9:
|
|
915
|
+
corrected = _c.sent();
|
|
916
|
+
assert(corrected.originalTotalDurationInMS === originalDuration, "originalTotalDurationInMS should be ".concat(originalDuration, ", got ").concat(corrected.originalTotalDurationInMS));
|
|
917
|
+
assert(corrected.totalDurationInMS === 5000, "totalDurationInMS should be corrected to 5000, got ".concat(corrected.totalDurationInMS));
|
|
918
|
+
log("E2: Original duration correctly preserved in originalTotalDurationInMS");
|
|
919
|
+
log("All edge case tests passed!");
|
|
920
|
+
return [3 /*break*/, 17];
|
|
921
|
+
case 10:
|
|
922
|
+
_i = 0, trackIds_5 = trackIds;
|
|
923
|
+
_c.label = 11;
|
|
924
|
+
case 11:
|
|
925
|
+
if (!(_i < trackIds_5.length)) return [3 /*break*/, 16];
|
|
926
|
+
id = trackIds_5[_i];
|
|
927
|
+
_c.label = 12;
|
|
928
|
+
case 12:
|
|
929
|
+
_c.trys.push([12, 14, , 15]);
|
|
930
|
+
return [4 /*yield*/, sdk.api.time_tracks.deleteOne(id)];
|
|
931
|
+
case 13:
|
|
932
|
+
_c.sent();
|
|
933
|
+
return [3 /*break*/, 15];
|
|
934
|
+
case 14:
|
|
935
|
+
e_8 = _c.sent();
|
|
936
|
+
return [3 /*break*/, 15];
|
|
937
|
+
case 15:
|
|
938
|
+
_i++;
|
|
939
|
+
return [3 /*break*/, 11];
|
|
940
|
+
case 16: return [7 /*endfinally*/];
|
|
941
|
+
case 17: return [2 /*return*/];
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
});
|
|
945
|
+
};
|
|
294
946
|
// Allow running this test file independently
|
|
295
947
|
if (require.main === module) {
|
|
296
948
|
var sdk_1 = new Session({ host: host });
|
|
@@ -308,6 +960,21 @@ if (require.main === module) {
|
|
|
308
960
|
_a.sent();
|
|
309
961
|
return [4 /*yield*/, time_tracks_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
310
962
|
case 2:
|
|
963
|
+
_a.sent();
|
|
964
|
+
return [4 /*yield*/, time_tracks_historical_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
965
|
+
case 3:
|
|
966
|
+
_a.sent();
|
|
967
|
+
return [4 /*yield*/, time_tracks_correction_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
968
|
+
case 4:
|
|
969
|
+
_a.sent();
|
|
970
|
+
return [4 /*yield*/, time_tracks_review_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
971
|
+
case 5:
|
|
972
|
+
_a.sent();
|
|
973
|
+
return [4 /*yield*/, time_tracks_lock_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
974
|
+
case 6:
|
|
975
|
+
_a.sent();
|
|
976
|
+
return [4 /*yield*/, time_tracks_edge_case_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
977
|
+
case 7:
|
|
311
978
|
_a.sent();
|
|
312
979
|
return [2 /*return*/];
|
|
313
980
|
}
|
|
@@ -315,11 +982,11 @@ if (require.main === module) {
|
|
|
315
982
|
}); };
|
|
316
983
|
runTests()
|
|
317
984
|
.then(function () {
|
|
318
|
-
console.log("
|
|
985
|
+
console.log("Time tracks test suite completed successfully");
|
|
319
986
|
process.exit(0);
|
|
320
987
|
})
|
|
321
988
|
.catch(function (error) {
|
|
322
|
-
console.error("
|
|
989
|
+
console.error("Time tracks test suite failed:", error);
|
|
323
990
|
process.exit(1);
|
|
324
991
|
});
|
|
325
992
|
}
|