@getjones/test-infra 3.0.2 → 3.1.2

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": "3.0.2",
3
+ "version": "3.1.2",
4
4
  "description": "Providing internal and openapi interface",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -3,9 +3,11 @@ const { expect } = require('chai');
3
3
  const threadScheduler = require('../../../saas/internal-api/thread-scheduler/runner');
4
4
  const timeUtils = require('../../utils/timeUtils');
5
5
  const httpResponseStatusCodes = require('../../../common/httpResponseStatusCodes.json');
6
+ const ocrStatuses = require('../../consts/ocrStatuses');
6
7
  const contractors = require('../../../saas/internal-api/contractors');
7
8
  const compliance = require('../../../saas/internal-api/compliance');
8
9
  const requests = require('../../../saas/internal-api/requests');
10
+ const dbEmails = require('../../../saas/internal-api/dbEmails');
9
11
 
10
12
  const makeRecordNotResponsive = async function(recordId, context, { isTenant } = {}) {
11
13
  const offsetInDaysList = isTenant ?
@@ -112,6 +114,25 @@ const getHistoryEvents = async function(recordId, context) {
112
114
  return recordHistory.data.map(item => item.itemTitle).reverse();
113
115
  };
114
116
 
117
+ const waitForOcrStatus = async function(recordId, context, { expectedStatus = ocrStatuses.SUCCESS } = {}) {
118
+ let { data: recordOcrStatus } = await contractors.services.getRecordOcrStatus(recordId, context);
119
+ let maxRetries = 25;
120
+ while (recordOcrStatus !== expectedStatus && recordOcrStatus !== ocrStatuses.FAILED && maxRetries > 0) {
121
+ await timeUtils.waitFor(5).seconds;
122
+ recordOcrStatus = (await contractors.services.getRecordOcrStatus(recordId, context)).data;
123
+ maxRetries--;
124
+ }
125
+
126
+ if (recordOcrStatus !== expectedStatus) {
127
+ throw new Error(`Record OCR status not is as expected. Expected: ${expectedStatus}, Actual: ${recordOcrStatus}`);
128
+ }
129
+ };
130
+
131
+ const generateSubscriptionModelFromMail = async function(recipients) {
132
+ const data = await dbEmails.services.getSubscriptionData(recipients);
133
+ return contractors.services.getSubscriptionModel(data);
134
+ };
135
+
115
136
  module.exports = {
116
137
  makeRecordNotResponsive,
117
138
  runOverAllRenewalDatesForRecord,
@@ -119,5 +140,7 @@ module.exports = {
119
140
  updateInviteDate,
120
141
  updatePolicyExpiryDateForRecord,
121
142
  getHistoryEvents,
122
- updateLastInviteActionDate
143
+ updateLastInviteActionDate,
144
+ waitForOcrStatus,
145
+ generateSubscriptionModelFromMail
123
146
  };
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ isOcrEnabled: {
3
+ on: { isOcrEnabled: true },
4
+ off: { isOcrEnabled: false }
5
+ },
6
+ isAccountRequirementsEnabled: {
7
+ on: { isAccountRequirementsEnabled: true },
8
+ off: { isAccountRequirementsEnabled: false }
9
+ }
10
+ };
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ SUCCESS: 'SUCCESS',
3
+ FAILED: 'FAILED',
4
+ IN_PROGRESS: 'IN_PROGRESS',
5
+ UNKNOWN: 'UNKNOWN'
6
+ };
@@ -6,12 +6,17 @@ const { credentials } = getEnv();
6
6
 
7
7
  const complianceStatuses = {
8
8
  complaint: 'complaint',
9
+ awaitingCoi: 'awaitingCoi',
9
10
  notCompliant: 'notCompliant',
10
- expired: 'expired',
11
- aboutToExpired: 'aboutToExpired',
11
+ waived: 'waived',
12
12
  awaitingNewCoi: 'awaitingNewCoi'
13
13
  };
14
14
 
15
+ const expiryStatuses = {
16
+ aboutToExpired: 'aboutToExpired',
17
+ expired: 'expired'
18
+ };
19
+
15
20
  const isReaudit = (contractorId, context) => {
16
21
  return auditApi.isReaudit(contractorId, context);
17
22
  };
@@ -61,17 +66,34 @@ const getAuditMetadata = async (
61
66
  return metadata;
62
67
  };
63
68
 
64
- const getAuditConfigByStatus = (status, { glPolicyNumber } = {}) => {
69
+ const getAuditConfigByStatus = (status, { expiryStatus, glPolicyNumber } = {}) => {
70
+ let config = {};
71
+
65
72
  switch (status) {
66
73
  case complianceStatuses.notCompliant:
67
74
  case complianceStatuses.awaitingNewCoi:
68
- return auditConfigs.getNotCompliantConfig({ glPolicyNumber });
69
- case complianceStatuses.expired:
70
- return auditConfigs.getExpiredConfig({ glPolicyNumber });
71
- case complianceStatuses.aboutToExpired:
72
- return auditConfigs.getAboutExpiredConfig({ glPolicyNumber });
75
+ case complianceStatuses.waived:
76
+ config = auditConfigs.getNotCompliantConfig({ glPolicyNumber });
77
+ break;
78
+ default:
79
+ config = auditConfigs.getCompliantAuditConfig({ glPolicyNumber });
80
+ }
81
+
82
+ expiryStatus && setExpiredByStatus(expiryStatus, config);
83
+
84
+ return config;
85
+ };
86
+
87
+ const setExpiredByStatus = (expiryStatus, config) => {
88
+ switch (expiryStatus) {
89
+ case expiryStatuses.expired:
90
+ auditConfigs.setExpiredConfig(config);
91
+ break;
92
+ case expiryStatuses.aboutToExpired:
93
+ auditConfigs.setAboutExpiredConfig(config);
94
+ break;
73
95
  default:
74
- return auditConfigs.getCompliantAuditConfig({ glPolicyNumber });
96
+ throw new Error(`Unknown expiry status: ${expiryStatus}`);
75
97
  }
76
98
  };
77
99
 
@@ -79,5 +101,6 @@ module.exports = {
79
101
  getAuditMetadata,
80
102
  isReaudit,
81
103
  getAuditConfigByStatus,
82
- complianceStatuses
104
+ complianceStatuses,
105
+ expiryStatuses
83
106
  };
@@ -68,22 +68,30 @@ const getNotCompliantConfig = ({ glPolicyNumber } = {}) => {
68
68
 
69
69
  const getAboutExpiredConfig = ({ glPolicyNumber } = {}) => {
70
70
  const compliantConfig = getCompliantAuditConfig({ glPolicyNumber });
71
- compliantConfig[generalLiability][policyExpired] = `${getOneWeekAheadDate()}`;
71
+ setAboutExpiredConfig(compliantConfig);
72
72
  return compliantConfig;
73
73
  };
74
74
 
75
75
  const getExpiredConfig = ({ glPolicyNumber } = {}) => {
76
76
  const compliantConfig = getCompliantAuditConfig({ glPolicyNumber });
77
- compliantConfig[generalLiability][policyExpired] = `${getOneWeekAgoDate()}`;
77
+ setExpiredConfig(compliantConfig);
78
78
 
79
79
  return compliantConfig;
80
80
  };
81
81
 
82
+ const setAboutExpiredConfig = config =>
83
+ config[generalLiability][policyExpired] = `${getOneWeekAheadDate()}`;
84
+
85
+ const setExpiredConfig = config =>
86
+ config[generalLiability][policyExpired] = `${getOneWeekAgoDate()}`;
87
+
82
88
  module.exports = {
83
89
  getCompliantAuditConfig,
84
90
  getNotCompliantConfig,
85
91
  getAboutExpiredConfig,
86
92
  getExpiredConfig,
93
+ setExpiredConfig,
94
+ setAboutExpiredConfig,
87
95
  policySelections,
88
96
  defaultPolicyDate: DEFAULT_POLICY_DATE,
89
97
  defaultAMScore: DEFAULT_AM_SCORE,
@@ -48,14 +48,17 @@ const attributeNames = {
48
48
  occur: 'Occur',
49
49
  text: 'text',
50
50
  limit: 'limit',
51
- AdditionalInsuredEndorsement: 'Additional Insured Endorsement',
52
- PrimaryNonContributoryProvision: 'Primary Non-Contributory Provision',
53
- PrimaryNonContributoryEndorsement: 'Primary Non-Contributory Endorsement',
51
+ additionalInsuredEndorsement: 'Additional Insured Endorsement',
52
+ primaryNonContributoryProvision: 'Primary Non-Contributory Provision',
53
+ primaryNonContributoryEndorsement: 'Primary Non-Contributory Endorsement',
54
54
  indemnityPeriod: 'Indemnity Period',
55
55
  actualLossSustained: 'Actual Loss Sustained',
56
56
  extraExpense: 'Extra Expense',
57
- combinedSingleLimit: 'Combined Single Limit'
58
-
57
+ combinedSingleLimit: 'Combined Single Limit',
58
+ followsForm: 'Follows Form',
59
+ followFormEndorsement: 'Follow-Form Endorsement',
60
+ waiverOfSubrogation: 'Waiver of Subrogation',
61
+ waiverOfSubrogationEndorsement: 'Waiver of Subrogation Endorsement'
59
62
  };
60
63
 
61
64
  module.exports = {
@@ -9,15 +9,18 @@ const compliance = require('../../saas/internal-api/compliance');
9
9
  const contractors = require('../../saas/internal-api/contractors');
10
10
  const requests = require('../../saas/internal-api/requests');
11
11
 
12
- const { complianceStatuses, getAuditConfigByStatus } = require('../../common/utils/complianceUtil');
12
+ const { complianceStatuses, getAuditConfigByStatus, expiryStatuses } = require('../../common/utils/complianceUtil');
13
13
  const httpResponseStatusCodes = require('../../common/httpResponseStatusCodes.json');
14
14
  const activationStatuses = require('../../common/consts/activationStatuses');
15
15
  const timeUtils = require('../../common/utils/timeUtils');
16
16
  const recordFlows = require('../../common/commonFlows/records/records');
17
+ const recordTypes = require('../../common/consts/recordTypes');
17
18
 
18
19
  const filePath = path.join(__dirname, '../../resources/coi/coi.pdf');
19
20
 
20
- const prepareRecord = async (recordCompany, recordEmail, status, tabId, requirementId, context, { shouldSendNotificationToPM = false, recordConfig } = {}) => {
21
+ const prepareRecord = async (recordCompany, recordEmail, status, tabId, requirementId, context, { expiryStatus, shouldSendNotificationToPM = false, recordConfig } = {}) => {
22
+ validateInsuranceAndExpiryStatus(status, expiryStatus);
23
+
21
24
  const requestData = await requests.services.getOrCreateRequest(
22
25
  context,
23
26
  tabId,
@@ -39,6 +42,10 @@ const prepareRecord = async (recordCompany, recordEmail, status, tabId, requirem
39
42
 
40
43
  recordConfig && await recordFlows.editRequestAndRecordDetails(requestData, recordConfig, context);
41
44
 
45
+ if (status === complianceStatuses.awaitingCoi) {
46
+ return recordId;
47
+ }
48
+
42
49
  const coiUpload = await coi.utils.uploadCoi(
43
50
  recordId,
44
51
  filePath,
@@ -56,7 +63,7 @@ const prepareRecord = async (recordCompany, recordEmail, status, tabId, requirem
56
63
 
57
64
  const auditorContext = await auth.services.getAuditorCookie();
58
65
 
59
- const auditConfig = getAuditConfigByStatus(status);
66
+ const auditConfig = getAuditConfigByStatus(status, { expiryStatus });
60
67
 
61
68
  let auditResponse, retries = 5;
62
69
  do {
@@ -76,37 +83,60 @@ const prepareRecord = async (recordCompany, recordEmail, status, tabId, requirem
76
83
  throw Error(`Failed to audit record ${recordCompany}\n${auditResponse}`);
77
84
  }
78
85
 
86
+ if (status === complianceStatuses.waived) {
87
+ await waiveAllGaps(recordId, context);
88
+ } else if (status === complianceStatuses.awaitingNewCoi) {
89
+ await sendGaps(recordId, tabId, context);
90
+ }
91
+
79
92
  return recordId;
80
93
  };
81
94
 
82
- const prepareCompliantRecord = (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig } = {}) => {
83
- return prepareRecord(recordCompany, recordEmail, complianceStatuses.complaint, tabId, requirementId, context, { recordConfig });
95
+ const prepareCompliantRecord = (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig, expiryStatus } = {}) => {
96
+ return prepareRecord(recordCompany, recordEmail, complianceStatuses.complaint, tabId, requirementId, context, { recordConfig, expiryStatus });
84
97
  };
85
98
 
86
- const prepareNotCompliantRecord = (recordCompany, recordEmail, tabId, requirementId, context, { shouldSendNotificationToPM = false, recordConfig } = {}) => {
87
- return prepareRecord(recordCompany, recordEmail, complianceStatuses.notCompliant, tabId, requirementId, context, { shouldSendNotificationToPM, recordConfig });
99
+ const prepareNotCompliantRecord = (recordCompany, recordEmail, tabId, requirementId, context, { shouldSendNotificationToPM = false, recordConfig, expiryStatus } = {}) => {
100
+ return prepareRecord(recordCompany, recordEmail, complianceStatuses.notCompliant, tabId, requirementId, context, { shouldSendNotificationToPM, recordConfig, expiryStatus });
88
101
  };
89
102
 
90
- const prepareExpiredRecord = (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig } = {}) => {
91
- return prepareRecord(recordCompany, recordEmail, complianceStatuses.expired, tabId, requirementId, context, { recordConfig });
103
+ const prepareWaivedRecord = async (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig, expiryStatus } = {}) => {
104
+ const recordId = await prepareRecord(recordCompany, recordEmail, complianceStatuses.notCompliant, tabId, requirementId, context, { recordConfig, expiryStatus });
105
+ await waiveAllGaps(recordId, context);
106
+ return recordId;
92
107
  };
93
108
 
94
- const prepareAboutToExpiredRecord = (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig } = {}) => {
95
- return prepareRecord(recordCompany, recordEmail, complianceStatuses.aboutToExpired, tabId, requirementId, context, { recordConfig });
109
+ const prepareAwaitingNewCoiRecord = async (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig, expiryStatus, isNotResponsive = false } = {}) => {
110
+ const recordId = await prepareRecord(recordCompany, recordEmail, complianceStatuses.awaitingNewCoi, tabId, requirementId, context, { recordConfig, expiryStatus });
111
+
112
+ if (isNotResponsive) {
113
+ await makeRecordNotResponsive(recordId, context);
114
+ }
115
+
116
+ return recordId;
96
117
  };
97
118
 
98
- const prepareWaivedRecord = async (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig } = {}) => {
99
- const recordId = await prepareRecord(recordCompany, recordEmail, complianceStatuses.notCompliant, tabId, requirementId, context, { recordConfig });
119
+ const prepareAwaitingCoiRecord = async (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig, isNotResponsive = false } = {}) => {
120
+ const recordId = await prepareRecord(recordCompany, recordEmail, complianceStatuses.awaitingCoi, tabId, requirementId, context, { recordConfig });
100
121
 
101
- const { data: record } = await contractors.services.getContractorById(recordId, context);
102
- await compliance.services.overrideGap.waiveAll(record, context);
122
+ if (isNotResponsive) {
123
+ await makeRecordNotResponsive(recordId, context);
124
+ }
103
125
 
104
126
  return recordId;
105
127
  };
106
128
 
107
- const prepareAwaitingNewCoiRecord = async (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig } = {}) => {
108
- const recordId = await prepareRecord(recordCompany, recordEmail, complianceStatuses.awaitingNewCoi, tabId, requirementId, context, { recordConfig });
129
+ const prepareUnderReviewRecord = (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig } = {}) => {
130
+ return prepareRecord(recordCompany, recordEmail, complianceStatuses.underReview, tabId, requirementId, context, { recordConfig });
131
+ };
132
+
133
+ const makeRecordNotResponsive = async (recordId, context) => {
134
+ const { data: record } = await contractors.services.getContractorById(recordId, context);
135
+ const isTenant = record.recordType === recordTypes.TENANTS;
136
+ await recordFlows.makeRecordNotResponsive(recordId, context, { isTenant });
137
+ };
109
138
 
139
+ const sendGaps = async (recordId, tabId, context) => {
110
140
  const { id: requestId } = await requests.services.getRequestFromTabByRecordId(recordId, tabId, context);
111
141
  const recordVerificationModel = await contractors.services.getRecordVerificationModel(recordId, context);
112
142
  const sendGapsResponse = await contractors.services.sendGaps(requestId, recordVerificationModel, context);
@@ -114,12 +144,39 @@ const prepareAwaitingNewCoiRecord = async (recordCompany, recordEmail, tabId, re
114
144
  if (sendGapsResponse.status !== httpResponseStatusCodes.OK) {
115
145
  throw Error(`Failed to send gaps to ${recordCompany}\n${sendGapsResponse}`);
116
146
  }
147
+ };
117
148
 
118
- return recordId;
149
+ const waiveAllGaps = async (recordId, context) => {
150
+ const { data: record } = await contractors.services.getContractorById(recordId, context);
151
+ await compliance.services.overrideGap.waiveAll(record, context);
119
152
  };
120
- const prepareUnderReviewRecord = (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig } = {}) => {
121
- return prepareRecord(recordCompany, recordEmail, complianceStatuses.underReview, tabId, requirementId, context, { recordConfig });
153
+
154
+ const validateInsuranceAndExpiryStatus = async (insuranceStatus, expiryStatus) => {
155
+ let isValid = false;
156
+ const isWithoutExpiryStatus = Boolean(expiryStatus);
157
+
158
+ switch (insuranceStatus) {
159
+ case complianceStatuses.complaint:
160
+ case complianceStatuses.waived:
161
+ isValid = isWithoutExpiryStatus || expiryStatus === expiryStatuses.aboutToExpired ;
162
+ break;
163
+ case complianceStatuses.awaitingNewCoi:
164
+ case complianceStatuses.notCompliant:
165
+ isValid = isWithoutExpiryStatus || Object.values(expiryStatuses).includes(expiryStatus) ;
166
+ break;
167
+ case complianceStatuses.awaitingCoi:
168
+ case complianceStatuses.underReview:
169
+ isValid = true;
170
+ break;
171
+ default:
172
+ throw new Error(`Invalid insurance status: ${insuranceStatus}`);
173
+ }
174
+
175
+ if (!isValid) {
176
+ throw new Error(`Invalid insurance and expiry status combination: insuranceStatus=${insuranceStatus}, expiryStatus=${expiryStatus}`);
177
+ }
122
178
  };
179
+
123
180
  const prepareDraftRecord = async (recordCompany, tabId, context, { recordEmail, requirementId, uploadCoi, recordConfig } = {}) => {
124
181
  const requestData = await requests.services.getOrCreateRequest(
125
182
  context,
@@ -160,10 +217,9 @@ const prepareDraftRecord = async (recordCompany, tabId, context, { recordEmail,
160
217
  module.exports = {
161
218
  prepareCompliantRecord,
162
219
  prepareNotCompliantRecord,
163
- prepareExpiredRecord,
164
220
  prepareWaivedRecord,
165
- prepareAboutToExpiredRecord,
166
221
  prepareAwaitingNewCoiRecord,
167
222
  prepareUnderReviewRecord,
223
+ prepareAwaitingCoiRecord,
168
224
  prepareDraftRecord
169
225
  };
@@ -7,6 +7,7 @@ const Endpoints = {
7
7
  get: `${backendUrl}/saas/contractors`,
8
8
  getContractorById: contractorId => `${backendUrl}/saas/contractor/${contractorId}`,
9
9
  getRecordHistory: contractorId => `${backendUrl}/saas/record/${contractorId}/history`,
10
+ getRecordOcrStatus: contractorId => `${backendUrl}/saas/contractor/${contractorId}/ocr/status`,
10
11
  delete: contractorId => `${backendUrl}/saas/contractor/${contractorId}`,
11
12
  archive: contractorId => `${backendUrl}/saas/contractor/${contractorId}/archive`,
12
13
  restore: contractorId => `${backendUrl}/saas/contractor/${contractorId}/restore`,
@@ -17,6 +18,8 @@ const Endpoints = {
17
18
  requestNewCoiExpired: requestId => `${backendUrl}/saas/coi/${requestId}/expired`,
18
19
  muteNotifications: `${backendUrl}/saas/record/notifications/mute`,
19
20
  unmuteNotifications: `${backendUrl}/saas/record/notifications/unmute`,
21
+ unsubscribe: `${backendUrl}/record/email/unsubscribe`,
22
+ subscribe: `${backendUrl}/record/email/subscribe`,
20
23
  changeRequirement: `${backendUrl}/saas/contractor/requirement`,
21
24
  updateVendorExpiryDate: contractorId => `${backendUrl}/_saas/automation/contractor/${contractorId}/expiry-date`,
22
25
  updateContractorInviteDate: contractorId => `${backendUrl}/_saas/automation/contractor/${contractorId}/invite-date`,
@@ -44,6 +47,10 @@ const getRecordHistory = (contractorId, context) => {
44
47
  return requests.getRequestHandler(Endpoints.getRecordHistory(contractorId), {}, context);
45
48
  };
46
49
 
50
+ const getRecordOcrStatus = (contractorId, context) => {
51
+ return requests.getRequestHandler(Endpoints.getRecordOcrStatus(contractorId), {}, context);
52
+ };
53
+
47
54
  const deleteByContractorId = (contractorId, context) => {
48
55
  return requests.deleteRequestHandler(Endpoints.delete(contractorId), context);
49
56
  };
@@ -70,6 +77,14 @@ const unmuteNotifications = (recordModifyDateVerificationModel, context) => {
70
77
  return requests.postRequestHandler(Endpoints.unmuteNotifications, recordModifyDateVerificationModel, context);
71
78
  };
72
79
 
80
+ const unsubscribe = subscriptionModel => {
81
+ return requests.postRequestHandler(Endpoints.unsubscribe, subscriptionModel);
82
+ };
83
+
84
+ const subscribe = subscriptionModel => {
85
+ return requests.postRequestHandler(Endpoints.subscribe, subscriptionModel);
86
+ };
87
+
73
88
  const changeRequirement = (recordModifyDateVerificationModel, context) => {
74
89
  return requests.putRequestHandler(Endpoints.changeRequirement, recordModifyDateVerificationModel, context);
75
90
  };
@@ -161,6 +176,7 @@ module.exports = {
161
176
  getContractorsByAccountId,
162
177
  getContractorById,
163
178
  getRecordHistory,
179
+ getRecordOcrStatus,
164
180
  deleteByContractorId,
165
181
  archiveRecord,
166
182
  restoreRecord,
@@ -176,6 +192,8 @@ module.exports = {
176
192
  resendInvitation,
177
193
  muteNotifications,
178
194
  unmuteNotifications,
195
+ unsubscribe,
196
+ subscribe,
179
197
  getLinkedProjectsCount,
180
198
  updateLastInviteActionDate,
181
199
  getInviteLinkStatus,
@@ -5,6 +5,7 @@ const { RecordModifyDateVerificationModel } = require('../models/verification.co
5
5
  const { AssignRequirementModel } = require('../models/assign.requirement.model');
6
6
  const { ContractorDetailsModel } = require('../models/edit.contractor.model');
7
7
  const { LinkRequestModel } = require('../models/link.request.model');
8
+ const { SubscriptionModel } = require('../models/subscription.contractor.model');
8
9
  const httpResponseStatusCodes = require('../../../../common/httpResponseStatusCodes.json');
9
10
  const { waitFor } = require('../../../../common/utils/timeUtils');
10
11
  const activationStatuses = require('../../../../common/consts/activationStatuses');
@@ -26,6 +27,10 @@ const getRecordHistory = (contractorId, context) => {
26
27
  return contractorsAPI.getRecordHistory(contractorId, context);
27
28
  };
28
29
 
30
+ const getRecordOcrStatus = (recordId, context) => {
31
+ return contractorsAPI.getRecordOcrStatus(recordId, context);
32
+ };
33
+
29
34
  const archiveRecord = (recordVerificationModel, context) => {
30
35
  validateType(recordVerificationModel, RecordModifyDateVerificationModel);
31
36
  return contractorsAPI.archiveRecord(recordVerificationModel, context);
@@ -100,11 +105,59 @@ const muteNotifications = (recordModifyDateVerificationModel, context) => {
100
105
  return contractorsAPI.muteNotifications(recordModifyDateVerificationModel, context);
101
106
  };
102
107
 
108
+ const muteNotificationsByRecordId = async (recordId, context) => {
109
+ const recordModifyDateVerificationModel = await getRecordVerificationModel(recordId, context);
110
+ const muteResponse = await contractorsAPI.muteNotifications(recordModifyDateVerificationModel, context);
111
+
112
+ if (muteResponse.status !== httpResponseStatusCodes.NO_CONTENT) {
113
+ throw new Error(`Failed to mute record: ${muteResponse.statusText}`);
114
+ }
115
+
116
+ return muteResponse;
117
+ };
118
+
103
119
  const unmuteNotifications = (recordModifyDateVerificationModel, context) => {
104
120
  validateType(recordModifyDateVerificationModel, RecordModifyDateVerificationModel);
105
121
  return contractorsAPI.unmuteNotifications(recordModifyDateVerificationModel, context);
106
122
  };
107
123
 
124
+ const unmuteNotificationsByRecordId = async (recordId, context) => {
125
+ const recordModifyDateVerificationModel = await getRecordVerificationModel(recordId, context);
126
+ const unmuteResponse = await contractorsAPI.unmuteNotifications(recordModifyDateVerificationModel, context);
127
+
128
+ if (unmuteResponse.status !== httpResponseStatusCodes.NO_CONTENT) {
129
+ throw new Error(`Failed to unmute record: ${unmuteResponse.statusText}`);
130
+ }
131
+
132
+ return unmuteResponse;
133
+ };
134
+
135
+ const unsubscribe = async (subscriptionModel, { expectError } = {}) => {
136
+ validateType(subscriptionModel, SubscriptionModel);
137
+ const unsubscribeResponse = await contractorsAPI.unsubscribe(subscriptionModel);
138
+
139
+ if (unsubscribeResponse.status !== httpResponseStatusCodes.OK && !expectError) {
140
+ throw new Error(`Failed to unsubscribe record: ${unsubscribeResponse.statusText}`);
141
+ }
142
+
143
+ return unsubscribeResponse;
144
+ };
145
+
146
+ const subscribe = async (subscriptionModel, { expectError } = {}) => {
147
+ validateType(subscriptionModel, SubscriptionModel);
148
+ const subscribeResponse = await contractorsAPI.subscribe(subscriptionModel);
149
+
150
+ if (subscribeResponse.status !== httpResponseStatusCodes.OK && !expectError) {
151
+ throw new Error(`Failed to subscribe record: ${subscribeResponse.statusText}`);
152
+ }
153
+
154
+ return subscribeResponse;
155
+ };
156
+
157
+ const getSubscriptionModel = (data, { recaptchaResponse = 'recaptchaResponse' } = {}) => {
158
+ return new SubscriptionModel(data, recaptchaResponse);
159
+ };
160
+
108
161
  const deleteByContractorId = (contractorId, context) => {
109
162
  return contractorsAPI.deleteByContractorId(contractorId, context);
110
163
  };
@@ -226,6 +279,7 @@ module.exports = {
226
279
  getContractorsByAccountId,
227
280
  getContractorById,
228
281
  getRecordHistory,
282
+ getRecordOcrStatus,
229
283
  archiveRecord,
230
284
  restoreRecord,
231
285
  editContractor,
@@ -239,7 +293,12 @@ module.exports = {
239
293
  requestNewCoiExpired,
240
294
  resendInvitation,
241
295
  muteNotifications,
296
+ muteNotificationsByRecordId,
242
297
  unmuteNotifications,
298
+ unmuteNotificationsByRecordId,
299
+ unsubscribe,
300
+ subscribe,
301
+ getSubscriptionModel,
243
302
  deleteByContractorId,
244
303
  deleteAllRecordsInAccount,
245
304
  deleteAllActiveRecordsInAccount,
@@ -0,0 +1,13 @@
1
+ class SubscriptionModel {
2
+ constructor(
3
+ data,
4
+ recaptchaResponse
5
+ ) {
6
+ this.data = data;
7
+ this.recaptchaResponse = recaptchaResponse;
8
+ }
9
+ }
10
+
11
+ module.exports = {
12
+ SubscriptionModel
13
+ };
@@ -137,11 +137,20 @@ const waitForMail = async (emailModel, { maxSecondToWait = 30 } = {}) => {
137
137
  return foundMails;
138
138
  };
139
139
 
140
+ const getSubscriptionData = async function(recipients) {
141
+ const regex = util.getUnsubscribeButtonUrlRegex();
142
+ const unsubscribeButtonUrl = await getLastMessage({ recipients, regex, returnType: 'url' });
143
+
144
+ const data = util.getEncryptedDataFromLink(unsubscribeButtonUrl);
145
+ return decodeURIComponent(data);
146
+ };
147
+
140
148
  module.exports = {
141
149
  util,
142
150
  waitForMail,
143
151
  getAllMessages,
144
152
  getLastMessage,
153
+ getSubscriptionData,
145
154
  deleteMultipleMessages,
146
155
  deleteAllMessages
147
156
  };
@@ -66,9 +66,13 @@ const getMailActionButtonUrlRegex = () => {
66
66
  return /(https:\/\/[a-zA-Z0-9.].*[a-zA-Z.]+\/CheckCustomersInviteLinkJSON\?data=[^"]+)/g;
67
67
  };
68
68
 
69
- const getEncryptedDataFromLink = link => {
69
+ const getUnsubscribeButtonUrlRegex = () => {
70
+ return /(\/[a-zA-Z0-9.].*[a-zA-Z.]+\/vendor-app\/email\/unsubscribe\?data=[^"]+)/g;
71
+ };
72
+
73
+ const getEncryptedDataFromLink = (link, { removeLastTwoCharts } = {}) => {
70
74
  const encryptedData = link.split('data=').pop();
71
- return encryptedData.slice(0, -2);
75
+ return removeLastTwoCharts ? encryptedData.slice(0, -2) : encryptedData;
72
76
  };
73
77
 
74
78
  module.exports = {
@@ -78,5 +82,6 @@ module.exports = {
78
82
  logRetrievedEmailInfo,
79
83
  getEmailTextInSubject,
80
84
  getMailActionButtonUrlRegex,
85
+ getUnsubscribeButtonUrlRegex,
81
86
  getEncryptedDataFromLink
82
87
  };