@getjones/test-infra 5.2.11 → 5.2.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getjones/test-infra",
3
- "version": "5.2.11",
3
+ "version": "5.2.12",
4
4
  "description": "Providing internal and openapi interface",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -20,6 +20,8 @@ const recordTypes = require('../../../common/consts/recordTypes');
20
20
  const policyNames = require('../../../defaults/index').polices;
21
21
  const { ExtractionRequestModel } = require('../../../saas/internal-api/requirements/models/extraction.request.model');
22
22
  const { TabExtractionRequestModel } = require('../../../saas/internal-api/requirements/models/tab.extraction.request.model');
23
+ const { DEFAULT_LEASE_PATH } = require('../../../saas/internal-api/requirements/consts/consts');
24
+ const { RELATED_DOC_TYPES } = require('../../../saas/internal-api/uploadFiles/consts');
23
25
  const { WAIVER_REASONS, EXPIRY_TYPES } = compliance.models.waive;
24
26
 
25
27
  const makeRecordNotResponsive = async function(recordId, context) {
@@ -392,18 +394,25 @@ const requestRequirementsExtraction = async (recordId, context, { leaseFilePath,
392
394
  };
393
395
 
394
396
  const requestTabRequirementsExtraction = async (tabId, context,
395
- { leaseFilePath, requirementName, notes, docType } = {}, { expectError, readContext = context } = {}) => {
397
+ { leaseFilePath = DEFAULT_LEASE_PATH, requirementName, notes, docType = RELATED_DOC_TYPES.SERVICE_AGREEMENT } = {}, { expectError, readContext = context } = {}) => {
396
398
  const stagedDocument = await uploadFile.services.stageDocumentToTempBucket(tabId, context, { filePath: leaseFilePath });
397
399
  const tabExtractionRequestModel = new TabExtractionRequestModel({ ... stagedDocument, requirementName, docType, notes });
400
+ const existingLeases = expectError ? [] : await requirements.lease.services.getLeasesByTabId(tabId, readContext, { openOnly: false });
401
+ const existingLeaseIds = new Set(existingLeases.map(({ leaseId }) => leaseId));
398
402
  const requestResponse = await requirements.lease.services.requestTabLeaseExtraction(tabId, tabExtractionRequestModel, context, { expectError });
399
403
 
400
404
  if (expectError) {
401
405
  return { requestResponse, stagedDocument };
402
406
  }
403
407
 
404
- const [lease] = await requirements.lease.services.getLeasesByTabId(tabId, readContext);
408
+ const openLeases = await requirements.lease.services.getLeasesByTabId(tabId, readContext);
409
+ const createdLease = openLeases.find(({ leaseId }) => !existingLeaseIds.has(leaseId));
405
410
 
406
- return lease.leaseId;
411
+ if (!createdLease) {
412
+ throw Error(`No new tab-level lease found for tab: ${tabId}`);
413
+ }
414
+
415
+ return createdLease.leaseId;
407
416
  };
408
417
 
409
418
  const cancelOpenTabRequests = async (tabId, icsContext) => {
@@ -4,6 +4,18 @@ const { credentials } = getEnv();
4
4
  const httpResponseStatusCodes = require('../../../../common/httpResponseStatusCodes.json');
5
5
 
6
6
  const authApi = require('./auth.api');
7
+ const timeUtils = require('../../../../common/utils/timeUtils');
8
+
9
+ const RETRYABLE_LOGIN_STATUSES = [
10
+ httpResponseStatusCodes.BAD_GATEWAY,
11
+ httpResponseStatusCodes.SERVICE_UNAVAILABLE,
12
+ httpResponseStatusCodes.GATEWAY_TIMEOUT
13
+ ];
14
+ const MAX_LOGIN_ATTEMPTS = 3;
15
+ const LOGIN_RETRY_DELAY_SECONDS = 1;
16
+
17
+ // Parallel callers for the same user share one login request
18
+ const pendingLogins = new Map();
7
19
 
8
20
  const getAuthCookie = async (email, password) => {
9
21
  const systemUser = getSystemUserIdentity(email);
@@ -12,9 +24,31 @@ const getAuthCookie = async (email, password) => {
12
24
  return systemUser.cookie;
13
25
  }
14
26
 
15
- try {
27
+ if (!pendingLogins.has(email)) {
28
+ const login = loginAndCacheCookie(email, password).finally(() => pendingLogins.delete(email));
29
+ pendingLogins.set(email, login);
30
+ }
31
+
32
+ return pendingLogins.get(email);
33
+ };
34
+
35
+ const loginWithRetry = async (email, password) => {
36
+ for (let attempt = 1; ; attempt++) {
16
37
  const response = await authApi.login(email, password);
17
38
 
39
+ if (!RETRYABLE_LOGIN_STATUSES.includes(response.status) || attempt === MAX_LOGIN_ATTEMPTS) {
40
+ return response;
41
+ }
42
+
43
+ console.warn(`Login for ${email} failed with status ${response.status}, retrying`);
44
+ await timeUtils.waitFor(LOGIN_RETRY_DELAY_SECONDS).seconds;
45
+ }
46
+ };
47
+
48
+ const loginAndCacheCookie = async (email, password) => {
49
+ try {
50
+ const response = await loginWithRetry(email, password);
51
+
18
52
  if (response.status !== httpResponseStatusCodes.OK) {
19
53
  throw Error(`Error: ${JSON.stringify(response.data)}`);
20
54
  }
@@ -12,9 +12,11 @@ const leaseExtractionStatus = {
12
12
  closedReqSet: 'CLOSED_REQ_SET'
13
13
  };
14
14
 
15
+ const DEFAULT_LEASE_PATH = 'packages/test-infra/src/resources/lease/defaultLease.pdf';
16
+
15
17
  const LEASE_TRIGGER_TYPES = {
16
18
  record: 'RECORD',
17
19
  tab: 'TAB'
18
20
  };
19
21
 
20
- module.exports = { REQUIREMENT_SHARING_LEVELS, leaseExtractionStatus, LEASE_TRIGGER_TYPES };
22
+ module.exports = { REQUIREMENT_SHARING_LEVELS, leaseExtractionStatus, LEASE_TRIGGER_TYPES, DEFAULT_LEASE_PATH };
@@ -1,11 +1,12 @@
1
1
  class NotificationSettingsModel {
2
- constructor({ aboutToExpire = true, auditCompliant = true, auditNotCompliant = true, missingCoi = true, recordOverrideRequest = true, timedOverrideExpired = true } = {}) {
2
+ constructor({ aboutToExpire = true, auditCompliant = true, auditNotCompliant = true, missingCoi = true, recordOverrideRequest = true, timedOverrideExpired = true, weeklySummary = true } = {}) {
3
3
  this.aboutToExpire = aboutToExpire;
4
4
  this.auditCompliant = auditCompliant;
5
5
  this.auditNotCompliant = auditNotCompliant;
6
6
  this.missingCoi = missingCoi;
7
7
  this.recordOverrideRequest = recordOverrideRequest;
8
8
  this.timedOverrideExpired = timedOverrideExpired;
9
+ this.weeklySummary = weeklySummary;
9
10
  }
10
11
  }
11
12
 
@@ -13,7 +13,8 @@ const attributesConvertor = {
13
13
  'COI is compliant.': 'auditCompliant',
14
14
  'Unresponsive contact.': 'missingCoi',
15
15
  'Record Override Request': 'recordOverrideRequest',
16
- 'Timed override expired — record is not compliant.': 'timedOverrideExpired'
16
+ 'Timed override expired — record is not compliant.': 'timedOverrideExpired',
17
+ 'Weekly summary': 'weeklySummary'
17
18
  };
18
19
 
19
20
  const getUserEncryptedData = async (email, role, context) => {