@contrail/flexplm 1.7.7-alpha.6568df9 → 1.7.7-alpha.7ad4e7e

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.
@@ -15,8 +15,6 @@ export declare class FlexPLMConnect {
15
15
  /** Runs a cold acquisition and registers it so concurrent callers wait for it instead of opening their own session. */
16
16
  private runColdAcquisition;
17
17
  private getSessionKey;
18
- /** Releases the connection of a rejected response before it is replaced by a retry. */
19
- private discardBody;
20
18
  private getCachedSession;
21
19
  private storeSession;
22
20
  private clearSession;
@@ -4,19 +4,6 @@ exports.FlexPLMConnect = void 0;
4
4
  const app_framework_1 = require("@contrail/app-framework");
5
5
  // Module-level on purpose: a new FlexPLMConnect is constructed for every event. Declaring for Session reusing use case.
6
6
  const sessionCache = new Map();
7
- // Upper bound so users/option combinations that are never requested again cannot accumulate cookies forever.
8
- const MAX_CACHED_SESSIONS = 100;
9
- const pruneSessionCache = () => {
10
- const now = Date.now();
11
- for (const [key, session] of sessionCache) {
12
- if (session.expiresAt <= now)
13
- sessionCache.delete(key);
14
- }
15
- // Still full: drop the oldest entries (Map keeps insertion order).
16
- while (sessionCache.size >= MAX_CACHED_SESSIONS) {
17
- sessionCache.delete(sessionCache.keys().next().value);
18
- }
19
- };
20
7
  // In-flight cold session acquisitions per key, so concurrent events share one FlexPLM session instead of each creating their own.
21
8
  const inFlightAcquisitions = new Map();
22
9
  const DEFAULT_SESSION_COOKIE_NAME = 'JSESSIONID';
@@ -36,11 +23,10 @@ const parseRetryStatuses = (value) => {
36
23
  else if (value !== undefined && value !== null)
37
24
  list = [value];
38
25
  const statuses = list
39
- .map(status => (typeof status === 'string' ? status.trim() : status))
40
- .filter(status => status !== '' && status !== null && status !== undefined)
26
+ .map(v => (typeof v === 'string' ? v.trim() : v))
27
+ .filter(v => v !== '' && v !== null && v !== undefined)
41
28
  .map(Number)
42
- // Only client-error statuses can mean "session rejected". 2xx/5xx would resend events the server already processed.
43
- .filter(status => Number.isInteger(status) && status >= 400 && status <= 499);
29
+ .filter(n => Number.isInteger(n) && n >= 100 && n <= 599);
44
30
  return statuses.length ? statuses : DEFAULT_RETRY_STATUSES;
45
31
  };
46
32
  const parseTtlSeconds = (value) => {
@@ -126,21 +112,7 @@ class FlexPLMConnect {
126
112
  }
127
113
  }
128
114
  getSessionKey() {
129
- // Options that change the cached value are part of the key; JSON avoids '|' collisions between fields.
130
- const { cookieName, ttlMs } = this.sessionOptions;
131
- return JSON.stringify([
132
- this.config.apiHost, this.config.urlContext, this.config.userName(), this.config.plmEnviornment, cookieName, ttlMs,
133
- ]);
134
- }
135
- /** Releases the connection of a rejected response before it is replaced by a retry. */
136
- async discardBody(response) {
137
- try {
138
- if (typeof response?.body?.cancel === 'function')
139
- await response.body.cancel();
140
- }
141
- catch (e) {
142
- // best effort: nothing to do if the body is already consumed or locked
143
- }
115
+ return [this.config.apiHost, this.config.urlContext, this.config.userName(), this.config.plmEnviornment].join('|');
144
116
  }
145
117
  getCachedSession() {
146
118
  if (!this.sessionOptions.enabled)
@@ -157,11 +129,7 @@ class FlexPLMConnect {
157
129
  }
158
130
  storeSession(cookie) {
159
131
  // sliding expiry: Windchill's session timeout is also sliding
160
- const key = this.getSessionKey();
161
- // delete first so a refreshed entry moves to the newest position (oldest-first eviction then acts as LRU)
162
- sessionCache.delete(key);
163
- pruneSessionCache();
164
- sessionCache.set(key, { cookie, expiresAt: Date.now() + this.sessionOptions.ttlMs });
132
+ sessionCache.set(this.getSessionKey(), { cookie, expiresAt: Date.now() + this.sessionOptions.ttlMs });
165
133
  }
166
134
  clearSession() {
167
135
  sessionCache.delete(this.getSessionKey());
@@ -243,7 +211,7 @@ class FlexPLMConnect {
243
211
  await wait;
244
212
  if (getNewSession) {
245
213
  const current = this.getCachedSession();
246
- if (rejectedCookie === undefined || !current || current === rejectedCookie)
214
+ if (!current || current === rejectedCookie)
247
215
  this.clearSession();
248
216
  }
249
217
  const cached = this.getCachedSession();
@@ -274,7 +242,6 @@ class FlexPLMConnect {
274
242
  // Added for Session reuse - ET-390 - Starts
275
243
  if (sentCookie && this.sessionOptions.retryStatuses.includes(response.status)) {
276
244
  console.warn('Cached FlexPLM session rejected on csrf call (status ' + response.status + '). Retrying with a new session.');
277
- await this.discardBody(response);
278
245
  throw new SessionRejectedError();
279
246
  }
280
247
  // Added for Session reuse - ET-390 - Ends
@@ -358,7 +325,6 @@ class FlexPLMConnect {
358
325
  let response = await this.sendRequest(csrf, payload);
359
326
  if (csrf.sessionCookie && this.sessionOptions.retryStatuses.includes(response.status)) {
360
327
  console.warn('FlexPLM rejected session/nonce (status ' + response.status + '). Getting a new session and retrying once.');
361
- await this.discardBody(response);
362
328
  csrf = await this.getCSRF(true, csrf.sessionCookie);
363
329
  response = await this.sendRequest(csrf, payload);
364
330
  }
@@ -438,7 +404,6 @@ class FlexPLMConnect {
438
404
  const first = await attempt();
439
405
  let response = first.response;
440
406
  if (first.sent && this.sessionOptions.retryStatuses.includes(response.status)) {
441
- await this.discardBody(response);
442
407
  if (this.getCachedSession() === first.sent)
443
408
  this.clearSession();
444
409
  response = (await attempt()).response;
@@ -156,7 +156,7 @@ describe('FlexPLMConnect session reuse', () => {
156
156
  expect(callHeaders(1).Cookie).toBe('JSESSIONID=abc.tomcat1');
157
157
  expect(callHeaders(1).CSRF_NONCE).toBe('n1');
158
158
  });
159
- it('should reuse the cached session on the next event (new FlexPLMConnect instance)', async () => {
159
+ it('reuses the cached session on the next event (new FlexPLMConnect instance)', async () => {
160
160
  const u = uniqueUser();
161
161
  fetchMock()
162
162
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1; Path=/'])) // event 1 GET
@@ -168,7 +168,7 @@ describe('FlexPLMConnect session reuse', () => {
168
168
  expect(callHeaders(2).Cookie).toBe('JSESSIONID=abc.tomcat1'); // GET reuses it
169
169
  expect(callHeaders(3).Cookie).toBe('JSESSIONID=abc.tomcat1'); // POST reuses it
170
170
  });
171
- it('should replace the cached session when Windchill answers the GET with a new Set-Cookie', async () => {
171
+ it('replaces the cached session when Windchill answers the GET with a new Set-Cookie', async () => {
172
172
  const u = uniqueUser();
173
173
  fetchMock()
174
174
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1; Path=/']))
@@ -185,7 +185,7 @@ describe('FlexPLMConnect session reuse', () => {
185
185
  expect(callHeaders(3).Cookie).toBe('JSESSIONID=new.tomcat1'); // POST uses the replacement
186
186
  expect(callHeaders(4).Cookie).toBe('JSESSIONID=new.tomcat1'); // event 3 GET sends the replacement
187
187
  });
188
- it('should retry once with a new session when the POST is rejected with 403', async () => {
188
+ it('retries once with a new session when the POST is rejected with 403', async () => {
189
189
  const u = uniqueUser();
190
190
  fetchMock()
191
191
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1; Path=/'])) // GET
@@ -199,7 +199,7 @@ describe('FlexPLMConnect session reuse', () => {
199
199
  expect(result.status).toBe(200);
200
200
  expect(result.data).toEqual({ ok: true });
201
201
  });
202
- it('should also retry on 401', async () => {
202
+ it('also retries on 401', async () => {
203
203
  const u = uniqueUser();
204
204
  fetchMock()
205
205
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1']))
@@ -209,7 +209,7 @@ describe('FlexPLMConnect session reuse', () => {
209
209
  await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u)).sendToFlexPLM(payload);
210
210
  expect(fetchMock()).toHaveBeenCalledTimes(4);
211
211
  });
212
- it('should not loop: a second 403 after the retry is surfaced as an error', async () => {
212
+ it('does not loop: a second 403 after the retry is surfaced as an error', async () => {
213
213
  const u = uniqueUser();
214
214
  fetchMock()
215
215
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1']))
@@ -220,7 +220,7 @@ describe('FlexPLMConnect session reuse', () => {
220
220
  .rejects.toThrow('Error sending data to FlexPLM:status: 403');
221
221
  expect(fetchMock()).toHaveBeenCalledTimes(4);
222
222
  });
223
- it('should not retry on non-auth errors such as 500 (event may already be processed)', async () => {
223
+ it('does not retry on non-auth errors such as 500 (event may already be processed)', async () => {
224
224
  const u = uniqueUser();
225
225
  fetchMock()
226
226
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1']))
@@ -229,7 +229,7 @@ describe('FlexPLMConnect session reuse', () => {
229
229
  .rejects.toThrow('Error sending data to FlexPLM:status: 500');
230
230
  expect(fetchMock()).toHaveBeenCalledTimes(2);
231
231
  });
232
- it('should retry the csrf GET without a cookie when the cached session is rejected there', async () => {
232
+ it('retries the csrf GET without a cookie when the cached session is rejected there', async () => {
233
233
  const u = uniqueUser();
234
234
  fetchMock()
235
235
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1'])) // event 1 GET
@@ -243,7 +243,7 @@ describe('FlexPLMConnect session reuse', () => {
243
243
  expect(callHeaders(3).Cookie).toBeUndefined();
244
244
  expect(callHeaders(4).Cookie).toBe('JSESSIONID=new.tomcat1');
245
245
  });
246
- it('should expire the cached session after ttlSeconds', async () => {
246
+ it('expires the cached session after ttlSeconds', async () => {
247
247
  const u = uniqueUser();
248
248
  const realNow = Date.now();
249
249
  const nowSpy = jest.spyOn(Date, 'now').mockReturnValue(realNow);
@@ -260,7 +260,7 @@ describe('FlexPLMConnect session reuse', () => {
260
260
  expect(callHeaders(3).Cookie).toBe('JSESSIONID=def.tomcat1');
261
261
  nowSpy.mockRestore();
262
262
  });
263
- it('should use the last JSESSIONID when several Set-Cookie lines are returned', async () => {
263
+ it('uses the last JSESSIONID when several Set-Cookie lines are returned', async () => {
264
264
  const u = uniqueUser();
265
265
  fetchMock()
266
266
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=first.tomcat1; Path=/', 'OTHER=x; Path=/', 'JSESSIONID=second.tomcat1; Path=/']))
@@ -268,7 +268,7 @@ describe('FlexPLMConnect session reuse', () => {
268
268
  await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u)).sendToFlexPLM(payload);
269
269
  expect(callHeaders(1).Cookie).toBe('JSESSIONID=second.tomcat1');
270
270
  });
271
- it('should fall back to headers.get("set-cookie") when getSetCookie is not available', async () => {
271
+ it('falls back to headers.get("set-cookie") when getSetCookie is not available', async () => {
272
272
  const u = uniqueUser();
273
273
  const legacy = {
274
274
  status: 200,
@@ -280,7 +280,7 @@ describe('FlexPLMConnect session reuse', () => {
280
280
  await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u)).sendToFlexPLM(payload);
281
281
  expect(callHeaders(1).Cookie).toBe('JSESSIONID=legacy.tomcat1');
282
282
  });
283
- it('should honour a custom cookieName', async () => {
283
+ it('honours a custom cookieName', async () => {
284
284
  const u = uniqueUser();
285
285
  fetchMock()
286
286
  .mockResolvedValueOnce(resp(200, ['MYSESSION=zzz; Path=/', 'JSESSIONID=ignored; Path=/']))
@@ -288,7 +288,7 @@ describe('FlexPLMConnect session reuse', () => {
288
288
  await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: true, cookieName: 'MYSESSION' })).sendToFlexPLM(payload);
289
289
  expect(callHeaders(1).Cookie).toBe('MYSESSION=zzz');
290
290
  });
291
- it('should accept enabled as the string "true"', async () => {
291
+ it('accepts enabled as the string "true"', async () => {
292
292
  const u = uniqueUser();
293
293
  fetchMock()
294
294
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1']))
@@ -296,39 +296,7 @@ describe('FlexPLMConnect session reuse', () => {
296
296
  await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: 'true' })).sendToFlexPLM(payload);
297
297
  expect(callHeaders(1).Cookie).toBe('JSESSIONID=abc.tomcat1');
298
298
  });
299
- it('should evict expired sessions of other users when a new session is stored', async () => {
300
- const userA = uniqueUser();
301
- const userB = uniqueUser();
302
- const realNow = Date.now();
303
- const nowSpy = jest.spyOn(Date, 'now').mockReturnValue(realNow);
304
- fetchMock()
305
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=a.tomcat1'])) // A GET
306
- .mockResolvedValueOnce(resp(200, [], {})) // A POST
307
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=b.tomcat1'])) // B GET
308
- .mockResolvedValueOnce(resp(200, [], {})) // B POST
309
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=a2.tomcat1'])) // A GET again
310
- .mockResolvedValueOnce(resp(200, [], {}));
311
- const cfg = (u) => sessionConfig(u, { enabled: true, ttlSeconds: 1 });
312
- await new flexplm_connect_1.FlexPLMConnect(cfg(userA)).sendToFlexPLM(payload);
313
- nowSpy.mockReturnValue(realNow + 2000); // A has expired
314
- await new flexplm_connect_1.FlexPLMConnect(cfg(userB)).sendToFlexPLM(payload); // storing B sweeps A
315
- nowSpy.mockReturnValue(realNow); // rewind: only a swept A has no entry left
316
- await new flexplm_connect_1.FlexPLMConnect(cfg(userA)).sendToFlexPLM(payload);
317
- expect(callHeaders(4).Cookie).toBeUndefined();
318
- nowSpy.mockRestore();
319
- });
320
- it('should not hold more than the maximum number of cached sessions', async () => {
321
- const first = uniqueUser();
322
- fetchMock().mockImplementation(async () => resp(200, ['JSESSIONID=s.tomcat1']));
323
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(first)).sendToFlexPLM(payload);
324
- for (let i = 0; i < 100; i++) {
325
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(uniqueUser())).sendToFlexPLM(payload);
326
- }
327
- fetchMock().mockClear();
328
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(first)).sendToFlexPLM(payload);
329
- expect(callHeaders(0).Cookie).toBeUndefined(); // oldest entry was evicted
330
- });
331
- it('should keep separate sessions per user', async () => {
299
+ it('keeps separate sessions per user', async () => {
332
300
  const a = uniqueUser();
333
301
  const b = uniqueUser();
334
302
  fetchMock()
@@ -341,7 +309,7 @@ describe('FlexPLMConnect session reuse', () => {
341
309
  expect(callHeaders(2).Cookie).toBeUndefined(); // user b must not see user a's cookie
342
310
  expect(callHeaders(3).Cookie).toBe('JSESSIONID=bbb.tomcat1');
343
311
  });
344
- it('should never log the cookie value', async () => {
312
+ it('never logs the cookie value', async () => {
345
313
  const isInfoOn = jest.spyOn(app_framework_1.Logger, 'isInfoOn').mockReturnValue(true);
346
314
  const info = jest.spyOn(console, 'info').mockImplementation();
347
315
  const u = uniqueUser();
@@ -372,11 +340,11 @@ describe('FlexPLMConnect session reuse', () => {
372
340
  ['a comma separated string', '401, 403'],
373
341
  ['garbage (falls back to 401/403)', 'abc'],
374
342
  ['an empty array (falls back to 401/403)', []],
375
- ])('should not throw and still retry on 403 when retryStatuses is %s', async (_label, retryStatuses) => {
343
+ ])('retryStatuses given as %s does not throw and still retries on 403', async (_label, retryStatuses) => {
376
344
  await rejectedOnceThenOk(uniqueUser(), { retryStatuses });
377
345
  expect(fetchMock()).toHaveBeenCalledTimes(4);
378
346
  });
379
- it.each([['abc'], [0], [-5]])('should fall back to the 900s default when ttlSeconds is invalid (%p)', async (ttlSeconds) => {
347
+ it.each([['abc'], [0], [-5]])('invalid ttlSeconds (%p) falls back to the 900s default', async (ttlSeconds) => {
380
348
  const u = uniqueUser();
381
349
  const realNow = Date.now();
382
350
  const nowSpy = jest.spyOn(Date, 'now').mockReturnValue(realNow);
@@ -392,7 +360,7 @@ describe('FlexPLMConnect session reuse', () => {
392
360
  expect(callHeaders(2).Cookie).toBe('JSESSIONID=abc.tomcat1');
393
361
  nowSpy.mockRestore();
394
362
  });
395
- it('should fall back to JSESSIONID when cookieName is blank', async () => {
363
+ it('a blank cookieName falls back to JSESSIONID', async () => {
396
364
  const u = uniqueUser();
397
365
  fetchMock()
398
366
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1']))
@@ -401,111 +369,8 @@ describe('FlexPLMConnect session reuse', () => {
401
369
  expect(callHeaders(1).Cookie).toBe('JSESSIONID=abc.tomcat1');
402
370
  });
403
371
  });
404
- describe('retryStatuses restricted to client-error statuses', () => {
405
- const postFailsWith = async (status, retryStatuses) => {
406
- const u = uniqueUser();
407
- fetchMock()
408
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1']))
409
- .mockResolvedValueOnce(resp(status, [], {}));
410
- await expect(new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: true, retryStatuses })).sendToFlexPLM({ id: '1' }))
411
- .rejects.toThrow('Error sending data to FlexPLM:status: ' + status);
412
- expect(fetchMock()).toHaveBeenCalledTimes(2); // no retry
413
- };
414
- it.each([[500], ['500'], [[200, 500]]])('should ignore non-4xx retryStatuses (%p) and not retry a 500', async (retryStatuses) => {
415
- await postFailsWith(500, retryStatuses);
416
- });
417
- it('should keep 4xx entries and drop others from a mixed retryStatuses list', async () => {
418
- await postFailsWith(500, [401, 500]);
419
- });
420
- it('should not resend a successful event when retryStatuses is configured as 200', async () => {
421
- const u = uniqueUser();
422
- fetchMock()
423
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1']))
424
- .mockResolvedValueOnce(resp(200, [], {}));
425
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: true, retryStatuses: 200 })).sendToFlexPLM({ id: '1' });
426
- expect(fetchMock()).toHaveBeenCalledTimes(2);
427
- });
428
- });
429
- describe('session cache key includes session options', () => {
430
- it('should not share a cached cookie between different cookieNames for the same user', async () => {
431
- const u = uniqueUser();
432
- fetchMock()
433
- .mockResolvedValueOnce(resp(200, ['AAA=a1; Path=/']))
434
- .mockResolvedValueOnce(resp(200, [], {}))
435
- .mockResolvedValueOnce(resp(200, ['BBB=b1; Path=/']))
436
- .mockResolvedValueOnce(resp(200, [], {}));
437
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: true, cookieName: 'AAA' })).sendToFlexPLM({ id: '1' });
438
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: true, cookieName: 'BBB' })).sendToFlexPLM({ id: '1' });
439
- expect(callHeaders(2).Cookie).toBeUndefined(); // BBB config must not pick up the AAA session
440
- expect(callHeaders(3).Cookie).toBe('BBB=b1');
441
- });
442
- it('should not share a cached session between different ttlSeconds for the same user', async () => {
443
- const u = uniqueUser();
444
- fetchMock()
445
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=short.tomcat1']))
446
- .mockResolvedValueOnce(resp(200, [], {}))
447
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=long.tomcat1']))
448
- .mockResolvedValueOnce(resp(200, [], {}));
449
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: true, ttlSeconds: 1 })).sendToFlexPLM({ id: '1' });
450
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: true, ttlSeconds: 900 })).sendToFlexPLM({ id: '1' });
451
- expect(callHeaders(2).Cookie).toBeUndefined();
452
- expect(callHeaders(3).Cookie).toBe('JSESSIONID=long.tomcat1');
453
- });
454
- });
455
- describe('rejected response disposal', () => {
456
- const withBody = (r) => Object.assign(r, { body: { cancel: jest.fn().mockResolvedValue(undefined) } });
457
- it('should cancel the body of a POST rejected with 403 before retrying', async () => {
458
- const u = uniqueUser();
459
- const rejected = withBody(resp(403, [], {}));
460
- fetchMock()
461
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1']))
462
- .mockResolvedValueOnce(rejected)
463
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=new.tomcat1']))
464
- .mockResolvedValueOnce(resp(200, [], {}));
465
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u)).sendToFlexPLM({ id: '1' });
466
- expect(rejected.body.cancel).toHaveBeenCalledTimes(1);
467
- });
468
- it('should cancel the body of a CSRF GET rejected with the cached cookie before retrying', async () => {
469
- const u = uniqueUser();
470
- const rejected = withBody(resp(401, []));
471
- fetchMock()
472
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1']))
473
- .mockResolvedValueOnce(resp(200, [], {}))
474
- .mockResolvedValueOnce(rejected)
475
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=new.tomcat1']))
476
- .mockResolvedValueOnce(resp(200, [], {}));
477
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u)).sendToFlexPLM({ id: '1' });
478
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u)).sendToFlexPLM({ id: '1' });
479
- expect(rejected.body.cancel).toHaveBeenCalledTimes(1);
480
- });
481
- it('should cancel the body of a getRequest rejected with the cached cookie before retrying', async () => {
482
- const u = uniqueUser();
483
- const rejected = withBody(resp(401, []));
484
- fetchMock()
485
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1']))
486
- .mockResolvedValueOnce(resp(200, [], {}))
487
- .mockResolvedValueOnce(rejected)
488
- .mockResolvedValueOnce(resp(200, [], { items: [] }));
489
- const connect = new flexplm_connect_1.FlexPLMConnect(sessionConfig(u));
490
- await connect.sendToFlexPLM({ id: '1' });
491
- await connect.getRequest();
492
- expect(rejected.body.cancel).toHaveBeenCalledTimes(1);
493
- });
494
- it('should still retry when cancelling the body throws', async () => {
495
- const u = uniqueUser();
496
- const rejected = resp(403, [], {});
497
- rejected.body = { cancel: jest.fn().mockRejectedValue(new Error('locked')) };
498
- fetchMock()
499
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1']))
500
- .mockResolvedValueOnce(rejected)
501
- .mockResolvedValueOnce(resp(200, ['JSESSIONID=new.tomcat1']))
502
- .mockResolvedValueOnce(resp(200, [], {}));
503
- await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u)).sendToFlexPLM({ id: '1' });
504
- expect(fetchMock()).toHaveBeenCalledTimes(4);
505
- });
506
- });
507
372
  describe('cookie names containing regex metacharacters', () => {
508
- it('should extract a cookie whose name contains "+"', async () => {
373
+ it('extracts a cookie whose name contains "+"', async () => {
509
374
  const u = uniqueUser();
510
375
  fetchMock()
511
376
  .mockResolvedValueOnce(resp(200, ['SID+=abc; Path=/']))
@@ -513,7 +378,7 @@ describe('FlexPLMConnect session reuse', () => {
513
378
  await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u, { enabled: true, cookieName: 'SID+' })).sendToFlexPLM(payload);
514
379
  expect(callHeaders(1).Cookie).toBe('SID+=abc');
515
380
  });
516
- it('should treat "." literally and not match a look-alike cookie', async () => {
381
+ it('treats "." literally and does not match a look-alike cookie', async () => {
517
382
  const u = uniqueUser();
518
383
  fetchMock()
519
384
  .mockResolvedValueOnce(resp(200, ['AxB=wrong; Path=/']))
@@ -525,7 +390,7 @@ describe('FlexPLMConnect session reuse', () => {
525
390
  describe('concurrent session acquisition', () => {
526
391
  const flush = () => new Promise(r => setImmediate(r));
527
392
  const isColdGet = (call) => call[1].method === 'GET' && !call[1].headers.Cookie;
528
- it('should share one session across concurrent events on a cold cache', async () => {
393
+ it('shares one session across concurrent events on a cold cache', async () => {
529
394
  const u = uniqueUser();
530
395
  let release;
531
396
  const gate = new Promise(r => { release = r; });
@@ -544,7 +409,7 @@ describe('FlexPLMConnect session reuse', () => {
544
409
  expect(fetchMock().mock.calls.filter(isColdGet)).toHaveLength(1);
545
410
  results.forEach(r => expect(r.sessionCookie).toBe('abc.tomcat1'));
546
411
  });
547
- it('should not make a waiter inherit the failure of the first acquisition', async () => {
412
+ it('a waiter does not inherit the failure of the first acquisition', async () => {
548
413
  const u = uniqueUser();
549
414
  let release;
550
415
  const gate = new Promise(r => { release = r; });
@@ -559,7 +424,7 @@ describe('FlexPLMConnect session reuse', () => {
559
424
  expect(await firstResult).toBeInstanceOf(Error);
560
425
  expect((await second).sessionCookie).toBe('abc.tomcat1');
561
426
  });
562
- it('should create only one replacement session for parallel events rejected with 403', async () => {
427
+ it('parallel events rejected with 403 create only one replacement session', async () => {
563
428
  const u = uniqueUser();
564
429
  fetchMock().mockResolvedValueOnce(resp(200, ['JSESSIONID=old.tomcat1']));
565
430
  await new flexplm_connect_1.FlexPLMConnect(sessionConfig(u)).getCSRF(); // prime the cache with the old session
@@ -579,7 +444,7 @@ describe('FlexPLMConnect session reuse', () => {
579
444
  });
580
445
  describe('FlexPLMConnect session reuse - feature disabled (default)', () => {
581
446
  const payload = { id: '123' };
582
- it('should send no Cookie header and make exactly one GET + one POST', async () => {
447
+ it('sends no Cookie header and makes exactly one GET + one POST', async () => {
583
448
  const u = uniqueUser();
584
449
  fetchMock()
585
450
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1'])) // Set-Cookie present but must be ignored
@@ -593,7 +458,7 @@ describe('FlexPLMConnect session reuse - feature disabled (default)', () => {
593
458
  expect(callHeaders(i).Cookie).toBeUndefined();
594
459
  }
595
460
  });
596
- it('should not retry on 403 (behaves exactly as before)', async () => {
461
+ it('does not retry on 403 (behaves exactly as before)', async () => {
597
462
  const u = uniqueUser();
598
463
  fetchMock()
599
464
  .mockResolvedValueOnce(resp(200))
@@ -602,7 +467,7 @@ describe('FlexPLMConnect session reuse - feature disabled (default)', () => {
602
467
  .rejects.toThrow('Error sending data to FlexPLM:status: 403');
603
468
  expect(fetchMock()).toHaveBeenCalledTimes(2);
604
469
  });
605
- it('should behave the same as not configured when enabled is false', async () => {
470
+ it('explicit enabled:false behaves the same as not configured', async () => {
606
471
  const u = uniqueUser();
607
472
  fetchMock()
608
473
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1']))
@@ -612,7 +477,7 @@ describe('FlexPLMConnect session reuse - feature disabled (default)', () => {
612
477
  });
613
478
  });
614
479
  describe('FlexPLMConnect.getRequest session reuse', () => {
615
- it('should send the cached cookie on image/GET requests', async () => {
480
+ it('sends the cached cookie on image/GET requests', async () => {
616
481
  const u = uniqueUser();
617
482
  fetchMock()
618
483
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1'])) // csrf GET primes the cache
@@ -623,7 +488,7 @@ describe('FlexPLMConnect.getRequest session reuse', () => {
623
488
  await connect.getRequest();
624
489
  expect(callHeaders(2).Cookie).toBe('JSESSIONID=abc.tomcat1');
625
490
  });
626
- it('should retry once without the cookie when the cached session is rejected on getRequest', async () => {
491
+ it('retries once without the cookie when the cached session is rejected on getRequest', async () => {
627
492
  const u = uniqueUser();
628
493
  fetchMock()
629
494
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=abc.tomcat1']))
@@ -636,7 +501,7 @@ describe('FlexPLMConnect.getRequest session reuse', () => {
636
501
  expect(callHeaders(2).Cookie).toBe('JSESSIONID=abc.tomcat1');
637
502
  expect(callHeaders(3).Cookie).toBeUndefined();
638
503
  });
639
- it('should not re-store the rejected cookie when the retry issues no Set-Cookie', async () => {
504
+ it('does not re-store the rejected cookie when the retry issues no Set-Cookie', async () => {
640
505
  const u = uniqueUser();
641
506
  fetchMock()
642
507
  .mockResolvedValueOnce(resp(200, ['JSESSIONID=stale.tomcat1']))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/flexplm",
3
- "version": "1.7.7-alpha.6568df9",
3
+ "version": "1.7.7-alpha.7ad4e7e",
4
4
  "description": "Library used for integration with flexplm.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",