@tellescope/sdk 1.236.1 → 1.236.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/lib/cjs/enduser.d.ts +20 -0
- package/lib/cjs/enduser.d.ts.map +1 -1
- package/lib/cjs/sdk.d.ts +42 -0
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js +1 -0
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.d.ts +9 -0
- package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.js +1399 -0
- package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.js.map +1 -0
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +111 -106
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/enduser.d.ts +20 -0
- package/lib/esm/enduser.d.ts.map +1 -1
- package/lib/esm/sdk.d.ts +42 -0
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js +1 -0
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/tests/api_tests/auto_merge_form_submission.test.d.ts +9 -0
- package/lib/esm/tests/api_tests/auto_merge_form_submission.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/auto_merge_form_submission.test.js +1372 -0
- package/lib/esm/tests/api_tests/auto_merge_form_submission.test.js.map +1 -0
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +111 -106
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/sdk.ts +2 -1
- package/src/tests/api_tests/auto_merge_form_submission.test.ts +876 -0
- package/src/tests/tests.ts +4 -1
- package/test_generated.pdf +0 -0
|
@@ -0,0 +1,1372 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
require('source-map-support').install();
|
|
38
|
+
import * as buffer from 'buffer';
|
|
39
|
+
import { Session, EnduserSession } from "../../sdk";
|
|
40
|
+
import { async_test, log_header, } from "@tellescope/testing";
|
|
41
|
+
import { setup_tests } from "../setup";
|
|
42
|
+
var host = process.env.API_URL || 'http://localhost:8080';
|
|
43
|
+
/**
|
|
44
|
+
* Helper: Create a form with auto-merge enabled and intake fields
|
|
45
|
+
*/
|
|
46
|
+
var createAutoMergeForm = function (sdk, autoMergeOnSubmission) {
|
|
47
|
+
if (autoMergeOnSubmission === void 0) { autoMergeOnSubmission = true; }
|
|
48
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
49
|
+
var form, fnameField, lnameField, emailField, phoneField, dobField, fields;
|
|
50
|
+
return __generator(this, function (_a) {
|
|
51
|
+
switch (_a.label) {
|
|
52
|
+
case 0: return [4 /*yield*/, sdk.api.forms.createOne({
|
|
53
|
+
title: 'Auto Merge Test Form',
|
|
54
|
+
allowPublicURL: true,
|
|
55
|
+
autoMergeOnSubmission: autoMergeOnSubmission,
|
|
56
|
+
})
|
|
57
|
+
// Add intake fields - must create sequentially due to previousFields dependencies
|
|
58
|
+
];
|
|
59
|
+
case 1:
|
|
60
|
+
form = _a.sent();
|
|
61
|
+
return [4 /*yield*/, sdk.api.form_fields.createOne({
|
|
62
|
+
formId: form.id,
|
|
63
|
+
title: 'First Name',
|
|
64
|
+
type: 'string',
|
|
65
|
+
intakeField: 'fname',
|
|
66
|
+
previousFields: [{ type: 'root', info: {} }]
|
|
67
|
+
})];
|
|
68
|
+
case 2:
|
|
69
|
+
fnameField = _a.sent();
|
|
70
|
+
return [4 /*yield*/, sdk.api.form_fields.createOne({
|
|
71
|
+
formId: form.id,
|
|
72
|
+
title: 'Last Name',
|
|
73
|
+
type: 'string',
|
|
74
|
+
intakeField: 'lname',
|
|
75
|
+
previousFields: [{ type: 'after', info: { fieldId: fnameField.id } }]
|
|
76
|
+
})];
|
|
77
|
+
case 3:
|
|
78
|
+
lnameField = _a.sent();
|
|
79
|
+
return [4 /*yield*/, sdk.api.form_fields.createOne({
|
|
80
|
+
formId: form.id,
|
|
81
|
+
title: 'Email',
|
|
82
|
+
type: 'email',
|
|
83
|
+
intakeField: 'email',
|
|
84
|
+
previousFields: [{ type: 'after', info: { fieldId: lnameField.id } }]
|
|
85
|
+
})];
|
|
86
|
+
case 4:
|
|
87
|
+
emailField = _a.sent();
|
|
88
|
+
return [4 /*yield*/, sdk.api.form_fields.createOne({
|
|
89
|
+
formId: form.id,
|
|
90
|
+
title: 'Phone',
|
|
91
|
+
type: 'phone',
|
|
92
|
+
intakeField: 'phone',
|
|
93
|
+
previousFields: [{ type: 'after', info: { fieldId: emailField.id } }]
|
|
94
|
+
})];
|
|
95
|
+
case 5:
|
|
96
|
+
phoneField = _a.sent();
|
|
97
|
+
return [4 /*yield*/, sdk.api.form_fields.createOne({
|
|
98
|
+
formId: form.id,
|
|
99
|
+
title: 'Date of Birth',
|
|
100
|
+
type: 'dateString',
|
|
101
|
+
intakeField: 'dateOfBirth',
|
|
102
|
+
previousFields: [{ type: 'after', info: { fieldId: phoneField.id } }]
|
|
103
|
+
})];
|
|
104
|
+
case 6:
|
|
105
|
+
dobField = _a.sent();
|
|
106
|
+
fields = [fnameField, lnameField, emailField, phoneField, dobField];
|
|
107
|
+
return [2 /*return*/, { form: form, fields: fields }];
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Helper: Submit a public form with skipMatch and get the created enduser ID
|
|
114
|
+
*/
|
|
115
|
+
var submitPublicFormWithSkipMatch = function (form, fields, values) { return __awaiter(void 0, void 0, void 0, function () {
|
|
116
|
+
var enduserSDK, _a, authToken, accessCode, enduserId, authedSDK, responses, fnameField, lnameField, emailField, phoneField, dobField;
|
|
117
|
+
return __generator(this, function (_b) {
|
|
118
|
+
switch (_b.label) {
|
|
119
|
+
case 0:
|
|
120
|
+
enduserSDK = new EnduserSession({ host: host, businessId: form.businessId });
|
|
121
|
+
return [4 /*yield*/, enduserSDK.api.form_responses.session_for_public_form({
|
|
122
|
+
formId: form.id,
|
|
123
|
+
businessId: form.businessId,
|
|
124
|
+
skipMatch: true,
|
|
125
|
+
})];
|
|
126
|
+
case 1:
|
|
127
|
+
_a = _b.sent(), authToken = _a.authToken, accessCode = _a.accessCode, enduserId = _a.enduserId;
|
|
128
|
+
authedSDK = new EnduserSession({ host: host, businessId: form.businessId, authToken: authToken });
|
|
129
|
+
responses = [];
|
|
130
|
+
fnameField = fields.find(function (f) { return f.intakeField === 'fname'; });
|
|
131
|
+
lnameField = fields.find(function (f) { return f.intakeField === 'lname'; });
|
|
132
|
+
emailField = fields.find(function (f) { return f.intakeField === 'email'; });
|
|
133
|
+
phoneField = fields.find(function (f) { return f.intakeField === 'phone'; });
|
|
134
|
+
dobField = fields.find(function (f) { return f.intakeField === 'dateOfBirth'; });
|
|
135
|
+
if (values.fname && fnameField) {
|
|
136
|
+
responses.push({ fieldId: fnameField.id, fieldTitle: fnameField.title, answer: { type: 'string', value: values.fname } });
|
|
137
|
+
}
|
|
138
|
+
if (values.lname && lnameField) {
|
|
139
|
+
responses.push({ fieldId: lnameField.id, fieldTitle: lnameField.title, answer: { type: 'string', value: values.lname } });
|
|
140
|
+
}
|
|
141
|
+
if (values.email && emailField) {
|
|
142
|
+
responses.push({ fieldId: emailField.id, fieldTitle: emailField.title, answer: { type: 'email', value: values.email } });
|
|
143
|
+
}
|
|
144
|
+
if (values.phone && phoneField) {
|
|
145
|
+
responses.push({ fieldId: phoneField.id, fieldTitle: phoneField.title, answer: { type: 'phone', value: values.phone } });
|
|
146
|
+
}
|
|
147
|
+
if (values.dateOfBirth && dobField) {
|
|
148
|
+
responses.push({ fieldId: dobField.id, fieldTitle: dobField.title, answer: { type: 'dateString', value: values.dateOfBirth } });
|
|
149
|
+
}
|
|
150
|
+
return [4 /*yield*/, authedSDK.api.form_responses.submit_form_response({
|
|
151
|
+
accessCode: accessCode,
|
|
152
|
+
responses: responses,
|
|
153
|
+
})];
|
|
154
|
+
case 2:
|
|
155
|
+
_b.sent();
|
|
156
|
+
return [2 /*return*/, { enduserId: enduserId, accessCode: accessCode, authedSDK: authedSDK }];
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}); };
|
|
160
|
+
/**
|
|
161
|
+
* Helper: Check if enduser has been deleted (immediate check, no polling)
|
|
162
|
+
* Since auto-merge is now synchronous, we don't need to poll
|
|
163
|
+
*/
|
|
164
|
+
var isEnduserDeleted = function (sdk, enduserId) { return __awaiter(void 0, void 0, void 0, function () {
|
|
165
|
+
var _a;
|
|
166
|
+
return __generator(this, function (_b) {
|
|
167
|
+
switch (_b.label) {
|
|
168
|
+
case 0:
|
|
169
|
+
_b.trys.push([0, 2, , 3]);
|
|
170
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(enduserId)];
|
|
171
|
+
case 1:
|
|
172
|
+
_b.sent();
|
|
173
|
+
return [2 /*return*/, false]; // Still exists
|
|
174
|
+
case 2:
|
|
175
|
+
_a = _b.sent();
|
|
176
|
+
return [2 /*return*/, true]; // Deleted
|
|
177
|
+
case 3: return [2 /*return*/];
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}); };
|
|
181
|
+
/**
|
|
182
|
+
* Main test function that can be called independently or as part of the test suite
|
|
183
|
+
*/
|
|
184
|
+
export var auto_merge_form_submission_tests = function (_a) {
|
|
185
|
+
var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
|
|
186
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
187
|
+
return __generator(this, function (_b) {
|
|
188
|
+
switch (_b.label) {
|
|
189
|
+
case 0:
|
|
190
|
+
log_header("Auto-Merge Form Submission Tests");
|
|
191
|
+
// Test 1: Happy Path - Merge by Email Match
|
|
192
|
+
return [4 /*yield*/, async_test("Auto-merge: Merge occurs when matching by email", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
193
|
+
var testEmail, destination, _a, form, fields, sourceId, sourceDeleted, updatedDestination, formResponses;
|
|
194
|
+
var _b;
|
|
195
|
+
return __generator(this, function (_c) {
|
|
196
|
+
switch (_c.label) {
|
|
197
|
+
case 0:
|
|
198
|
+
testEmail = "automerge.email.".concat(Date.now(), "@test.com");
|
|
199
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
200
|
+
fname: 'John',
|
|
201
|
+
lname: 'Doe',
|
|
202
|
+
email: testEmail
|
|
203
|
+
})];
|
|
204
|
+
case 1:
|
|
205
|
+
destination = _c.sent();
|
|
206
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
207
|
+
case 2:
|
|
208
|
+
_a = _c.sent(), form = _a.form, fields = _a.fields;
|
|
209
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
210
|
+
fname: 'John',
|
|
211
|
+
lname: 'Doe',
|
|
212
|
+
email: testEmail,
|
|
213
|
+
})
|
|
214
|
+
// Merge is synchronous - source should be deleted immediately after submission
|
|
215
|
+
];
|
|
216
|
+
case 3:
|
|
217
|
+
sourceId = (_c.sent()).enduserId;
|
|
218
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
219
|
+
case 4:
|
|
220
|
+
sourceDeleted = _c.sent();
|
|
221
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(destination.id)];
|
|
222
|
+
case 5:
|
|
223
|
+
updatedDestination = _c.sent();
|
|
224
|
+
return [4 /*yield*/, sdk.api.form_responses.getSome({ filter: { enduserId: destination.id } })
|
|
225
|
+
// Cleanup
|
|
226
|
+
];
|
|
227
|
+
case 6:
|
|
228
|
+
formResponses = _c.sent();
|
|
229
|
+
// Cleanup
|
|
230
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
231
|
+
case 7:
|
|
232
|
+
// Cleanup
|
|
233
|
+
_c.sent();
|
|
234
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
235
|
+
case 8:
|
|
236
|
+
_c.sent();
|
|
237
|
+
return [2 /*return*/, sourceDeleted
|
|
238
|
+
&& ((_b = updatedDestination.mergedIds) === null || _b === void 0 ? void 0 : _b.includes(sourceId))
|
|
239
|
+
&& formResponses.length === 1];
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}); }, { expectedResult: true })
|
|
243
|
+
// Test 2: Happy Path - Merge by Phone Match
|
|
244
|
+
];
|
|
245
|
+
case 1:
|
|
246
|
+
// Test 1: Happy Path - Merge by Email Match
|
|
247
|
+
_b.sent();
|
|
248
|
+
// Test 2: Happy Path - Merge by Phone Match
|
|
249
|
+
return [4 /*yield*/, async_test("Auto-merge: Merge occurs when matching by phone", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
250
|
+
var testPhone, destination, _a, form, fields, sourceId, sourceDeleted, updatedDestination;
|
|
251
|
+
var _b;
|
|
252
|
+
return __generator(this, function (_c) {
|
|
253
|
+
switch (_c.label) {
|
|
254
|
+
case 0:
|
|
255
|
+
testPhone = '+15555551234';
|
|
256
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
257
|
+
fname: 'Jane',
|
|
258
|
+
lname: 'Smith',
|
|
259
|
+
phone: testPhone
|
|
260
|
+
})];
|
|
261
|
+
case 1:
|
|
262
|
+
destination = _c.sent();
|
|
263
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
264
|
+
case 2:
|
|
265
|
+
_a = _c.sent(), form = _a.form, fields = _a.fields;
|
|
266
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
267
|
+
fname: 'Jane',
|
|
268
|
+
lname: 'Smith',
|
|
269
|
+
phone: testPhone,
|
|
270
|
+
})
|
|
271
|
+
// Merge is synchronous - source should be deleted immediately after submission
|
|
272
|
+
];
|
|
273
|
+
case 3:
|
|
274
|
+
sourceId = (_c.sent()).enduserId;
|
|
275
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
276
|
+
case 4:
|
|
277
|
+
sourceDeleted = _c.sent();
|
|
278
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(destination.id)
|
|
279
|
+
// Cleanup
|
|
280
|
+
];
|
|
281
|
+
case 5:
|
|
282
|
+
updatedDestination = _c.sent();
|
|
283
|
+
// Cleanup
|
|
284
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
285
|
+
case 6:
|
|
286
|
+
// Cleanup
|
|
287
|
+
_c.sent();
|
|
288
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
289
|
+
case 7:
|
|
290
|
+
_c.sent();
|
|
291
|
+
return [2 /*return*/, sourceDeleted && ((_b = updatedDestination.mergedIds) === null || _b === void 0 ? void 0 : _b.includes(sourceId))];
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}); }, { expectedResult: true })
|
|
295
|
+
// Test 3: Happy Path - Merge by DateOfBirth Match
|
|
296
|
+
];
|
|
297
|
+
case 2:
|
|
298
|
+
// Test 2: Happy Path - Merge by Phone Match
|
|
299
|
+
_b.sent();
|
|
300
|
+
// Test 3: Happy Path - Merge by DateOfBirth Match
|
|
301
|
+
return [4 /*yield*/, async_test("Auto-merge: Merge occurs when matching by dateOfBirth", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
302
|
+
var testDOB, destination, _a, form, fields, sourceId, sourceDeleted, updatedDestination;
|
|
303
|
+
var _b;
|
|
304
|
+
return __generator(this, function (_c) {
|
|
305
|
+
switch (_c.label) {
|
|
306
|
+
case 0:
|
|
307
|
+
testDOB = '1990-05-15';
|
|
308
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
309
|
+
fname: 'Bob',
|
|
310
|
+
lname: 'Johnson',
|
|
311
|
+
dateOfBirth: testDOB
|
|
312
|
+
})];
|
|
313
|
+
case 1:
|
|
314
|
+
destination = _c.sent();
|
|
315
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
316
|
+
case 2:
|
|
317
|
+
_a = _c.sent(), form = _a.form, fields = _a.fields;
|
|
318
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
319
|
+
fname: 'Bob',
|
|
320
|
+
lname: 'Johnson',
|
|
321
|
+
dateOfBirth: testDOB,
|
|
322
|
+
})
|
|
323
|
+
// Merge is synchronous - source should be deleted immediately after submission
|
|
324
|
+
];
|
|
325
|
+
case 3:
|
|
326
|
+
sourceId = (_c.sent()).enduserId;
|
|
327
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
328
|
+
case 4:
|
|
329
|
+
sourceDeleted = _c.sent();
|
|
330
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(destination.id)
|
|
331
|
+
// Cleanup
|
|
332
|
+
];
|
|
333
|
+
case 5:
|
|
334
|
+
updatedDestination = _c.sent();
|
|
335
|
+
// Cleanup
|
|
336
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
337
|
+
case 6:
|
|
338
|
+
// Cleanup
|
|
339
|
+
_c.sent();
|
|
340
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
341
|
+
case 7:
|
|
342
|
+
_c.sent();
|
|
343
|
+
return [2 /*return*/, sourceDeleted && ((_b = updatedDestination.mergedIds) === null || _b === void 0 ? void 0 : _b.includes(sourceId))];
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
}); }, { expectedResult: true })
|
|
347
|
+
// Test 4: No Merge - Multiple Matches
|
|
348
|
+
];
|
|
349
|
+
case 3:
|
|
350
|
+
// Test 3: Happy Path - Merge by DateOfBirth Match
|
|
351
|
+
_b.sent();
|
|
352
|
+
// Test 4: No Merge - Multiple Matches
|
|
353
|
+
return [4 /*yield*/, async_test("Auto-merge: No merge when multiple matches found", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
354
|
+
var testDOB, destination1, destination2, _a, form, fields, sourceId, sourceDeleted, dest1, dest2;
|
|
355
|
+
var _b, _c;
|
|
356
|
+
return __generator(this, function (_d) {
|
|
357
|
+
switch (_d.label) {
|
|
358
|
+
case 0:
|
|
359
|
+
testDOB = '1975-01-15';
|
|
360
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
361
|
+
fname: 'Multi',
|
|
362
|
+
lname: 'Match',
|
|
363
|
+
dateOfBirth: testDOB
|
|
364
|
+
})];
|
|
365
|
+
case 1:
|
|
366
|
+
destination1 = _d.sent();
|
|
367
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
368
|
+
fname: 'Multi',
|
|
369
|
+
lname: 'Match',
|
|
370
|
+
dateOfBirth: testDOB
|
|
371
|
+
})];
|
|
372
|
+
case 2:
|
|
373
|
+
destination2 = _d.sent();
|
|
374
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
375
|
+
case 3:
|
|
376
|
+
_a = _d.sent(), form = _a.form, fields = _a.fields;
|
|
377
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
378
|
+
fname: 'Multi',
|
|
379
|
+
lname: 'Match',
|
|
380
|
+
dateOfBirth: testDOB,
|
|
381
|
+
})
|
|
382
|
+
// Merge is synchronous - no need to wait, source should still exist
|
|
383
|
+
];
|
|
384
|
+
case 4:
|
|
385
|
+
sourceId = (_d.sent()).enduserId;
|
|
386
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
387
|
+
case 5:
|
|
388
|
+
sourceDeleted = _d.sent();
|
|
389
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(destination1.id)];
|
|
390
|
+
case 6:
|
|
391
|
+
dest1 = _d.sent();
|
|
392
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(destination2.id)
|
|
393
|
+
// Cleanup
|
|
394
|
+
];
|
|
395
|
+
case 7:
|
|
396
|
+
dest2 = _d.sent();
|
|
397
|
+
// Cleanup
|
|
398
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
399
|
+
case 8:
|
|
400
|
+
// Cleanup
|
|
401
|
+
_d.sent();
|
|
402
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination1.id)];
|
|
403
|
+
case 9:
|
|
404
|
+
_d.sent();
|
|
405
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination2.id)];
|
|
406
|
+
case 10:
|
|
407
|
+
_d.sent();
|
|
408
|
+
if (!!sourceDeleted) return [3 /*break*/, 12];
|
|
409
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(sourceId)];
|
|
410
|
+
case 11:
|
|
411
|
+
_d.sent();
|
|
412
|
+
_d.label = 12;
|
|
413
|
+
case 12: return [2 /*return*/, !sourceDeleted // Source should NOT be deleted
|
|
414
|
+
&& !((_b = dest1.mergedIds) === null || _b === void 0 ? void 0 : _b.includes(sourceId))
|
|
415
|
+
&& !((_c = dest2.mergedIds) === null || _c === void 0 ? void 0 : _c.includes(sourceId))];
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}); }, { expectedResult: true })
|
|
419
|
+
// Test 5: No Merge - autoMergeOnSubmission Disabled
|
|
420
|
+
];
|
|
421
|
+
case 4:
|
|
422
|
+
// Test 4: No Merge - Multiple Matches
|
|
423
|
+
_b.sent();
|
|
424
|
+
// Test 5: No Merge - autoMergeOnSubmission Disabled
|
|
425
|
+
return [4 /*yield*/, async_test("Auto-merge: No merge when autoMergeOnSubmission is disabled", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
426
|
+
var testEmail, destination, _a, form, fields, sourceId, sourceDeleted;
|
|
427
|
+
return __generator(this, function (_b) {
|
|
428
|
+
switch (_b.label) {
|
|
429
|
+
case 0:
|
|
430
|
+
testEmail = "automerge.disabled.".concat(Date.now(), "@test.com");
|
|
431
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
432
|
+
fname: 'Disabled',
|
|
433
|
+
lname: 'Test',
|
|
434
|
+
email: testEmail
|
|
435
|
+
})];
|
|
436
|
+
case 1:
|
|
437
|
+
destination = _b.sent();
|
|
438
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, false)]; // Disabled
|
|
439
|
+
case 2:
|
|
440
|
+
_a = _b.sent() // Disabled
|
|
441
|
+
, form = _a.form, fields = _a.fields;
|
|
442
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
443
|
+
fname: 'Disabled',
|
|
444
|
+
lname: 'Test',
|
|
445
|
+
email: testEmail,
|
|
446
|
+
})
|
|
447
|
+
// Merge is synchronous - no need to wait, source should still exist
|
|
448
|
+
];
|
|
449
|
+
case 3:
|
|
450
|
+
sourceId = (_b.sent()).enduserId;
|
|
451
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)
|
|
452
|
+
// Cleanup
|
|
453
|
+
];
|
|
454
|
+
case 4:
|
|
455
|
+
sourceDeleted = _b.sent();
|
|
456
|
+
// Cleanup
|
|
457
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
458
|
+
case 5:
|
|
459
|
+
// Cleanup
|
|
460
|
+
_b.sent();
|
|
461
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
462
|
+
case 6:
|
|
463
|
+
_b.sent();
|
|
464
|
+
if (!!sourceDeleted) return [3 /*break*/, 8];
|
|
465
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(sourceId)];
|
|
466
|
+
case 7:
|
|
467
|
+
_b.sent();
|
|
468
|
+
_b.label = 8;
|
|
469
|
+
case 8: return [2 /*return*/, !sourceDeleted]; // Source should NOT be deleted
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
}); }, { expectedResult: true })
|
|
473
|
+
// Test 6: No Merge - No Matching Enduser
|
|
474
|
+
];
|
|
475
|
+
case 5:
|
|
476
|
+
// Test 5: No Merge - autoMergeOnSubmission Disabled
|
|
477
|
+
_b.sent();
|
|
478
|
+
// Test 6: No Merge - No Matching Enduser
|
|
479
|
+
return [4 /*yield*/, async_test("Auto-merge: No merge when no matching enduser exists", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
480
|
+
var _a, form, fields, sourceId, sourceDeleted;
|
|
481
|
+
return __generator(this, function (_b) {
|
|
482
|
+
switch (_b.label) {
|
|
483
|
+
case 0: return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
484
|
+
case 1:
|
|
485
|
+
_a = _b.sent(), form = _a.form, fields = _a.fields;
|
|
486
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
487
|
+
fname: 'NoMatch',
|
|
488
|
+
lname: 'Person',
|
|
489
|
+
email: "nomatch.".concat(Date.now(), "@test.com"),
|
|
490
|
+
})
|
|
491
|
+
// Merge is synchronous - no need to wait, source should still exist (no match found)
|
|
492
|
+
];
|
|
493
|
+
case 2:
|
|
494
|
+
sourceId = (_b.sent()).enduserId;
|
|
495
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)
|
|
496
|
+
// Cleanup
|
|
497
|
+
];
|
|
498
|
+
case 3:
|
|
499
|
+
sourceDeleted = _b.sent();
|
|
500
|
+
// Cleanup
|
|
501
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
502
|
+
case 4:
|
|
503
|
+
// Cleanup
|
|
504
|
+
_b.sent();
|
|
505
|
+
if (!!sourceDeleted) return [3 /*break*/, 6];
|
|
506
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(sourceId)];
|
|
507
|
+
case 5:
|
|
508
|
+
_b.sent();
|
|
509
|
+
_b.label = 6;
|
|
510
|
+
case 6: return [2 /*return*/, !sourceDeleted]; // Source should NOT be deleted
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
}); }, { expectedResult: true })
|
|
514
|
+
// Test 7: Case Sensitive Matching - No Merge When Case Differs
|
|
515
|
+
];
|
|
516
|
+
case 6:
|
|
517
|
+
// Test 6: No Merge - No Matching Enduser
|
|
518
|
+
_b.sent();
|
|
519
|
+
// Test 7: Case Sensitive Matching - No Merge When Case Differs
|
|
520
|
+
return [4 /*yield*/, async_test("Auto-merge: No merge when case differs (case-sensitive matching)", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
521
|
+
var testEmail, destination, _a, form, fields, sourceId, sourceDeleted, updatedDestination;
|
|
522
|
+
var _b;
|
|
523
|
+
return __generator(this, function (_c) {
|
|
524
|
+
switch (_c.label) {
|
|
525
|
+
case 0:
|
|
526
|
+
testEmail = "automerge.case.".concat(Date.now(), "@test.com");
|
|
527
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
528
|
+
fname: 'Case',
|
|
529
|
+
lname: 'Test',
|
|
530
|
+
email: testEmail
|
|
531
|
+
})];
|
|
532
|
+
case 1:
|
|
533
|
+
destination = _c.sent();
|
|
534
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)
|
|
535
|
+
// Submit with different case - should NOT match due to case-sensitive matching
|
|
536
|
+
];
|
|
537
|
+
case 2:
|
|
538
|
+
_a = _c.sent(), form = _a.form, fields = _a.fields;
|
|
539
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
540
|
+
fname: 'CASE',
|
|
541
|
+
lname: 'TEST',
|
|
542
|
+
email: testEmail.toUpperCase(), // Different case
|
|
543
|
+
})
|
|
544
|
+
// Merge is case-sensitive - source should still exist (no match found)
|
|
545
|
+
];
|
|
546
|
+
case 3:
|
|
547
|
+
sourceId = (_c.sent()).enduserId;
|
|
548
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
549
|
+
case 4:
|
|
550
|
+
sourceDeleted = _c.sent();
|
|
551
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(destination.id)
|
|
552
|
+
// Cleanup
|
|
553
|
+
];
|
|
554
|
+
case 5:
|
|
555
|
+
updatedDestination = _c.sent();
|
|
556
|
+
// Cleanup
|
|
557
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
558
|
+
case 6:
|
|
559
|
+
// Cleanup
|
|
560
|
+
_c.sent();
|
|
561
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
562
|
+
case 7:
|
|
563
|
+
_c.sent();
|
|
564
|
+
if (!!sourceDeleted) return [3 /*break*/, 9];
|
|
565
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(sourceId)];
|
|
566
|
+
case 8:
|
|
567
|
+
_c.sent();
|
|
568
|
+
_c.label = 9;
|
|
569
|
+
case 9: return [2 /*return*/, !sourceDeleted // Source should NOT be deleted (no merge)
|
|
570
|
+
&& !((_b = updatedDestination.mergedIds) === null || _b === void 0 ? void 0 : _b.includes(sourceId))];
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
}); }, { expectedResult: true })
|
|
574
|
+
// Test 8: eligibleForAutoMerge Flag Verification
|
|
575
|
+
];
|
|
576
|
+
case 7:
|
|
577
|
+
// Test 7: Case Sensitive Matching - No Merge When Case Differs
|
|
578
|
+
_b.sent();
|
|
579
|
+
// Test 8: eligibleForAutoMerge Flag Verification
|
|
580
|
+
return [4 /*yield*/, async_test("Auto-merge: eligibleForAutoMerge flag is set correctly", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
581
|
+
var _a, formEnabled, fieldsEnabled, enduserSDKEnabled, enabledEnduserId, enabledEnduser, _b, formDisabled, fieldsDisabled, enduserSDKDisabled, disabledEnduserId, disabledEnduser;
|
|
582
|
+
return __generator(this, function (_c) {
|
|
583
|
+
switch (_c.label) {
|
|
584
|
+
case 0: return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
585
|
+
case 1:
|
|
586
|
+
_a = _c.sent(), formEnabled = _a.form, fieldsEnabled = _a.fields;
|
|
587
|
+
enduserSDKEnabled = new EnduserSession({ host: host, businessId: formEnabled.businessId });
|
|
588
|
+
return [4 /*yield*/, enduserSDKEnabled.api.form_responses.session_for_public_form({
|
|
589
|
+
formId: formEnabled.id,
|
|
590
|
+
businessId: formEnabled.businessId,
|
|
591
|
+
skipMatch: true,
|
|
592
|
+
})];
|
|
593
|
+
case 2:
|
|
594
|
+
enabledEnduserId = (_c.sent()).enduserId;
|
|
595
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(enabledEnduserId)
|
|
596
|
+
// Form with autoMergeOnSubmission: false
|
|
597
|
+
];
|
|
598
|
+
case 3:
|
|
599
|
+
enabledEnduser = _c.sent();
|
|
600
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, false)];
|
|
601
|
+
case 4:
|
|
602
|
+
_b = _c.sent(), formDisabled = _b.form, fieldsDisabled = _b.fields;
|
|
603
|
+
enduserSDKDisabled = new EnduserSession({ host: host, businessId: formDisabled.businessId });
|
|
604
|
+
return [4 /*yield*/, enduserSDKDisabled.api.form_responses.session_for_public_form({
|
|
605
|
+
formId: formDisabled.id,
|
|
606
|
+
businessId: formDisabled.businessId,
|
|
607
|
+
skipMatch: true,
|
|
608
|
+
})];
|
|
609
|
+
case 5:
|
|
610
|
+
disabledEnduserId = (_c.sent()).enduserId;
|
|
611
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(disabledEnduserId)
|
|
612
|
+
// Cleanup
|
|
613
|
+
];
|
|
614
|
+
case 6:
|
|
615
|
+
disabledEnduser = _c.sent();
|
|
616
|
+
// Cleanup
|
|
617
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(formEnabled.id)];
|
|
618
|
+
case 7:
|
|
619
|
+
// Cleanup
|
|
620
|
+
_c.sent();
|
|
621
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(formDisabled.id)];
|
|
622
|
+
case 8:
|
|
623
|
+
_c.sent();
|
|
624
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(enabledEnduserId)];
|
|
625
|
+
case 9:
|
|
626
|
+
_c.sent();
|
|
627
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(disabledEnduserId)];
|
|
628
|
+
case 10:
|
|
629
|
+
_c.sent();
|
|
630
|
+
return [2 /*return*/, enabledEnduser.eligibleForAutoMerge === true
|
|
631
|
+
&& disabledEnduser.eligibleForAutoMerge !== true];
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
}); }, { expectedResult: true })
|
|
635
|
+
// Test 9: Files Transfer on Merge
|
|
636
|
+
];
|
|
637
|
+
case 8:
|
|
638
|
+
// Test 8: eligibleForAutoMerge Flag Verification
|
|
639
|
+
_b.sent();
|
|
640
|
+
// Test 9: Files Transfer on Merge
|
|
641
|
+
return [4 /*yield*/, async_test("Auto-merge: Files are transferred to destination enduser", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
642
|
+
var testEmail, destination, _a, form, fields, enduserSDK, _b, authToken, accessCode, sourceId, buff, _c, presignedUpload, file, authedSDK, fnameField, lnameField, emailField, sourceDeleted, updatedFile;
|
|
643
|
+
return __generator(this, function (_d) {
|
|
644
|
+
switch (_d.label) {
|
|
645
|
+
case 0:
|
|
646
|
+
testEmail = "automerge.files.".concat(Date.now(), "@test.com");
|
|
647
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
648
|
+
fname: 'Files',
|
|
649
|
+
lname: 'Test',
|
|
650
|
+
email: testEmail
|
|
651
|
+
})];
|
|
652
|
+
case 1:
|
|
653
|
+
destination = _d.sent();
|
|
654
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)
|
|
655
|
+
// Create public session to get source enduser
|
|
656
|
+
];
|
|
657
|
+
case 2:
|
|
658
|
+
_a = _d.sent(), form = _a.form, fields = _a.fields;
|
|
659
|
+
enduserSDK = new EnduserSession({ host: host, businessId: form.businessId });
|
|
660
|
+
return [4 /*yield*/, enduserSDK.api.form_responses.session_for_public_form({
|
|
661
|
+
formId: form.id,
|
|
662
|
+
businessId: form.businessId,
|
|
663
|
+
skipMatch: true,
|
|
664
|
+
})
|
|
665
|
+
// Create a file for the source enduser using prepare_file_upload + UPLOAD
|
|
666
|
+
];
|
|
667
|
+
case 3:
|
|
668
|
+
_b = _d.sent(), authToken = _b.authToken, accessCode = _b.accessCode, sourceId = _b.enduserId;
|
|
669
|
+
buff = buffer.Buffer.from('test file data for auto-merge');
|
|
670
|
+
return [4 /*yield*/, sdk.api.files.prepare_file_upload({
|
|
671
|
+
name: 'test-file.txt',
|
|
672
|
+
type: 'text/plain',
|
|
673
|
+
size: buff.byteLength,
|
|
674
|
+
enduserId: sourceId,
|
|
675
|
+
})];
|
|
676
|
+
case 4:
|
|
677
|
+
_c = _d.sent(), presignedUpload = _c.presignedUpload, file = _c.file;
|
|
678
|
+
return [4 /*yield*/, sdk.UPLOAD(presignedUpload, buff)
|
|
679
|
+
// Now submit the form to trigger merge
|
|
680
|
+
];
|
|
681
|
+
case 5:
|
|
682
|
+
_d.sent();
|
|
683
|
+
authedSDK = new EnduserSession({ host: host, businessId: form.businessId, authToken: authToken });
|
|
684
|
+
fnameField = fields.find(function (f) { return f.intakeField === 'fname'; });
|
|
685
|
+
lnameField = fields.find(function (f) { return f.intakeField === 'lname'; });
|
|
686
|
+
emailField = fields.find(function (f) { return f.intakeField === 'email'; });
|
|
687
|
+
return [4 /*yield*/, authedSDK.api.form_responses.submit_form_response({
|
|
688
|
+
accessCode: accessCode,
|
|
689
|
+
responses: [
|
|
690
|
+
{ fieldId: fnameField.id, fieldTitle: fnameField.title, answer: { type: 'string', value: 'Files' } },
|
|
691
|
+
{ fieldId: lnameField.id, fieldTitle: lnameField.title, answer: { type: 'string', value: 'Test' } },
|
|
692
|
+
{ fieldId: emailField.id, fieldTitle: emailField.title, answer: { type: 'email', value: testEmail } },
|
|
693
|
+
],
|
|
694
|
+
})
|
|
695
|
+
// Merge is synchronous - source should be deleted immediately after submission
|
|
696
|
+
];
|
|
697
|
+
case 6:
|
|
698
|
+
_d.sent();
|
|
699
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
700
|
+
case 7:
|
|
701
|
+
sourceDeleted = _d.sent();
|
|
702
|
+
return [4 /*yield*/, sdk.api.files.getOne(file.id)
|
|
703
|
+
// Cleanup
|
|
704
|
+
];
|
|
705
|
+
case 8:
|
|
706
|
+
updatedFile = _d.sent();
|
|
707
|
+
// Cleanup
|
|
708
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
709
|
+
case 9:
|
|
710
|
+
// Cleanup
|
|
711
|
+
_d.sent();
|
|
712
|
+
return [4 /*yield*/, sdk.api.files.deleteOne(file.id)];
|
|
713
|
+
case 10:
|
|
714
|
+
_d.sent();
|
|
715
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
716
|
+
case 11:
|
|
717
|
+
_d.sent();
|
|
718
|
+
return [2 /*return*/, sourceDeleted && updatedFile.enduserId === destination.id];
|
|
719
|
+
}
|
|
720
|
+
});
|
|
721
|
+
}); }, { expectedResult: true })
|
|
722
|
+
// Test 10: Calendar Events Transfer on Merge
|
|
723
|
+
];
|
|
724
|
+
case 9:
|
|
725
|
+
// Test 9: Files Transfer on Merge
|
|
726
|
+
_b.sent();
|
|
727
|
+
// Test 10: Calendar Events Transfer on Merge
|
|
728
|
+
return [4 /*yield*/, async_test("Auto-merge: Calendar events are transferred to destination enduser", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
729
|
+
var testEmail, destination, _a, form, fields, enduserSDK, _b, authToken, accessCode, sourceId, event, authedSDK, fnameField, lnameField, emailField, sourceDeleted, updatedEvent;
|
|
730
|
+
var _c;
|
|
731
|
+
return __generator(this, function (_d) {
|
|
732
|
+
switch (_d.label) {
|
|
733
|
+
case 0:
|
|
734
|
+
testEmail = "automerge.events.".concat(Date.now(), "@test.com");
|
|
735
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
736
|
+
fname: 'Events',
|
|
737
|
+
lname: 'Test',
|
|
738
|
+
email: testEmail
|
|
739
|
+
})];
|
|
740
|
+
case 1:
|
|
741
|
+
destination = _d.sent();
|
|
742
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)
|
|
743
|
+
// Create public session to get source enduser
|
|
744
|
+
];
|
|
745
|
+
case 2:
|
|
746
|
+
_a = _d.sent(), form = _a.form, fields = _a.fields;
|
|
747
|
+
enduserSDK = new EnduserSession({ host: host, businessId: form.businessId });
|
|
748
|
+
return [4 /*yield*/, enduserSDK.api.form_responses.session_for_public_form({
|
|
749
|
+
formId: form.id,
|
|
750
|
+
businessId: form.businessId,
|
|
751
|
+
skipMatch: true,
|
|
752
|
+
})
|
|
753
|
+
// Create a calendar event with source enduser as attendee
|
|
754
|
+
];
|
|
755
|
+
case 3:
|
|
756
|
+
_b = _d.sent(), authToken = _b.authToken, accessCode = _b.accessCode, sourceId = _b.enduserId;
|
|
757
|
+
return [4 /*yield*/, sdk.api.calendar_events.createOne({
|
|
758
|
+
title: 'Test Event',
|
|
759
|
+
startTimeInMS: Date.now() + 86400000,
|
|
760
|
+
durationInMinutes: 30,
|
|
761
|
+
attendees: [{ id: sourceId, type: 'enduser' }],
|
|
762
|
+
})
|
|
763
|
+
// Now submit the form to trigger merge
|
|
764
|
+
];
|
|
765
|
+
case 4:
|
|
766
|
+
event = _d.sent();
|
|
767
|
+
authedSDK = new EnduserSession({ host: host, businessId: form.businessId, authToken: authToken });
|
|
768
|
+
fnameField = fields.find(function (f) { return f.intakeField === 'fname'; });
|
|
769
|
+
lnameField = fields.find(function (f) { return f.intakeField === 'lname'; });
|
|
770
|
+
emailField = fields.find(function (f) { return f.intakeField === 'email'; });
|
|
771
|
+
return [4 /*yield*/, authedSDK.api.form_responses.submit_form_response({
|
|
772
|
+
accessCode: accessCode,
|
|
773
|
+
responses: [
|
|
774
|
+
{ fieldId: fnameField.id, fieldTitle: fnameField.title, answer: { type: 'string', value: 'Events' } },
|
|
775
|
+
{ fieldId: lnameField.id, fieldTitle: lnameField.title, answer: { type: 'string', value: 'Test' } },
|
|
776
|
+
{ fieldId: emailField.id, fieldTitle: emailField.title, answer: { type: 'email', value: testEmail } },
|
|
777
|
+
],
|
|
778
|
+
})
|
|
779
|
+
// Merge is synchronous - source should be deleted immediately after submission
|
|
780
|
+
];
|
|
781
|
+
case 5:
|
|
782
|
+
_d.sent();
|
|
783
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
784
|
+
case 6:
|
|
785
|
+
sourceDeleted = _d.sent();
|
|
786
|
+
return [4 /*yield*/, sdk.api.calendar_events.getOne(event.id)
|
|
787
|
+
// Cleanup
|
|
788
|
+
];
|
|
789
|
+
case 7:
|
|
790
|
+
updatedEvent = _d.sent();
|
|
791
|
+
// Cleanup
|
|
792
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
793
|
+
case 8:
|
|
794
|
+
// Cleanup
|
|
795
|
+
_d.sent();
|
|
796
|
+
return [4 /*yield*/, sdk.api.calendar_events.deleteOne(event.id)];
|
|
797
|
+
case 9:
|
|
798
|
+
_d.sent();
|
|
799
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
800
|
+
case 10:
|
|
801
|
+
_d.sent();
|
|
802
|
+
return [2 /*return*/, sourceDeleted && ((_c = updatedEvent.attendees) === null || _c === void 0 ? void 0 : _c.some(function (a) { return a.id === destination.id; }))];
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
}); }, { expectedResult: true })
|
|
806
|
+
// Test 11: Form response enduserId is updated to destination (placeholder is updated before submission completes)
|
|
807
|
+
];
|
|
808
|
+
case 10:
|
|
809
|
+
// Test 10: Calendar Events Transfer on Merge
|
|
810
|
+
_b.sent();
|
|
811
|
+
// Test 11: Form response enduserId is updated to destination (placeholder is updated before submission completes)
|
|
812
|
+
return [4 /*yield*/, async_test("Auto-merge: Form response enduserId is updated to destination", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
813
|
+
var testEmail, destination, _a, form, fields, _b, sourceId, accessCode, sourceDeleted, formResponses, createdFormResponse;
|
|
814
|
+
return __generator(this, function (_c) {
|
|
815
|
+
switch (_c.label) {
|
|
816
|
+
case 0:
|
|
817
|
+
testEmail = "automerge.directfr.".concat(Date.now(), "@test.com");
|
|
818
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
819
|
+
fname: 'Direct',
|
|
820
|
+
lname: 'Response',
|
|
821
|
+
email: testEmail
|
|
822
|
+
})];
|
|
823
|
+
case 1:
|
|
824
|
+
destination = _c.sent();
|
|
825
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
826
|
+
case 2:
|
|
827
|
+
_a = _c.sent(), form = _a.form, fields = _a.fields;
|
|
828
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
829
|
+
fname: 'Direct',
|
|
830
|
+
lname: 'Response',
|
|
831
|
+
email: testEmail,
|
|
832
|
+
})
|
|
833
|
+
// Merge is synchronous - verify form response was created with destination ID
|
|
834
|
+
];
|
|
835
|
+
case 3:
|
|
836
|
+
_b = _c.sent(), sourceId = _b.enduserId, accessCode = _b.accessCode;
|
|
837
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)
|
|
838
|
+
// Get form responses by accessCode to find the one we created
|
|
839
|
+
];
|
|
840
|
+
case 4:
|
|
841
|
+
sourceDeleted = _c.sent();
|
|
842
|
+
return [4 /*yield*/, sdk.api.form_responses.getSome({ filter: { accessCode: accessCode } })];
|
|
843
|
+
case 5:
|
|
844
|
+
formResponses = _c.sent();
|
|
845
|
+
createdFormResponse = formResponses[0];
|
|
846
|
+
// Cleanup
|
|
847
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
848
|
+
case 6:
|
|
849
|
+
// Cleanup
|
|
850
|
+
_c.sent();
|
|
851
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)
|
|
852
|
+
// The form response should have been created directly with destination enduser ID
|
|
853
|
+
// (not transferred after creation)
|
|
854
|
+
];
|
|
855
|
+
case 7:
|
|
856
|
+
_c.sent();
|
|
857
|
+
// The form response should have been created directly with destination enduser ID
|
|
858
|
+
// (not transferred after creation)
|
|
859
|
+
return [2 /*return*/, sourceDeleted
|
|
860
|
+
&& createdFormResponse !== undefined
|
|
861
|
+
&& createdFormResponse.enduserId === destination.id];
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
}); }, { expectedResult: true })
|
|
865
|
+
// Test 12: Intake fields update destination enduser directly
|
|
866
|
+
];
|
|
867
|
+
case 11:
|
|
868
|
+
// Test 11: Form response enduserId is updated to destination (placeholder is updated before submission completes)
|
|
869
|
+
_b.sent();
|
|
870
|
+
// Test 12: Intake fields update destination enduser directly
|
|
871
|
+
return [4 /*yield*/, async_test("Auto-merge: Intake fields update destination enduser directly", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
872
|
+
var testEmail, destination, _a, form, fields, newPhone, newDOB, sourceId, sourceDeleted, updatedDestination;
|
|
873
|
+
return __generator(this, function (_b) {
|
|
874
|
+
switch (_b.label) {
|
|
875
|
+
case 0:
|
|
876
|
+
testEmail = "automerge.intake.".concat(Date.now(), "@test.com");
|
|
877
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
878
|
+
fname: 'Intake',
|
|
879
|
+
lname: 'Test',
|
|
880
|
+
email: testEmail,
|
|
881
|
+
// No phone or DOB set initially
|
|
882
|
+
})];
|
|
883
|
+
case 1:
|
|
884
|
+
destination = _b.sent();
|
|
885
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
886
|
+
case 2:
|
|
887
|
+
_a = _b.sent(), form = _a.form, fields = _a.fields;
|
|
888
|
+
newPhone = '+15555559876';
|
|
889
|
+
newDOB = '1985-03-20';
|
|
890
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
891
|
+
fname: 'Intake',
|
|
892
|
+
lname: 'Test',
|
|
893
|
+
email: testEmail,
|
|
894
|
+
phone: newPhone,
|
|
895
|
+
dateOfBirth: newDOB,
|
|
896
|
+
})
|
|
897
|
+
// Merge is synchronous - verify intake fields updated destination directly
|
|
898
|
+
];
|
|
899
|
+
case 3:
|
|
900
|
+
sourceId = (_b.sent()).enduserId;
|
|
901
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
902
|
+
case 4:
|
|
903
|
+
sourceDeleted = _b.sent();
|
|
904
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(destination.id)
|
|
905
|
+
// Cleanup
|
|
906
|
+
];
|
|
907
|
+
case 5:
|
|
908
|
+
updatedDestination = _b.sent();
|
|
909
|
+
// Cleanup
|
|
910
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
911
|
+
case 6:
|
|
912
|
+
// Cleanup
|
|
913
|
+
_b.sent();
|
|
914
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)
|
|
915
|
+
// Intake fields should have been applied to the destination enduser
|
|
916
|
+
];
|
|
917
|
+
case 7:
|
|
918
|
+
_b.sent();
|
|
919
|
+
// Intake fields should have been applied to the destination enduser
|
|
920
|
+
return [2 /*return*/, sourceDeleted
|
|
921
|
+
&& updatedDestination.phone === newPhone
|
|
922
|
+
&& updatedDestination.dateOfBirth === newDOB];
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
}); }, { expectedResult: true })
|
|
926
|
+
// Test 13: eligibleForAutoMerge is unset after submission (no merge case)
|
|
927
|
+
];
|
|
928
|
+
case 12:
|
|
929
|
+
// Test 12: Intake fields update destination enduser directly
|
|
930
|
+
_b.sent();
|
|
931
|
+
// Test 13: eligibleForAutoMerge is unset after submission (no merge case)
|
|
932
|
+
return [4 /*yield*/, async_test("Auto-merge: eligibleForAutoMerge is unset after submission when no merge occurs", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
933
|
+
var _a, form, fields, sourceId, updatedEnduser;
|
|
934
|
+
return __generator(this, function (_b) {
|
|
935
|
+
switch (_b.label) {
|
|
936
|
+
case 0: return [4 /*yield*/, createAutoMergeForm(sdk, true)
|
|
937
|
+
// Submit form - no match exists, so no merge will happen
|
|
938
|
+
];
|
|
939
|
+
case 1:
|
|
940
|
+
_a = _b.sent(), form = _a.form, fields = _a.fields;
|
|
941
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
942
|
+
fname: 'Unset',
|
|
943
|
+
lname: 'Flag',
|
|
944
|
+
email: "unset.flag.".concat(Date.now(), "@test.com"),
|
|
945
|
+
})
|
|
946
|
+
// Verify enduser still exists and eligibleForAutoMerge is unset
|
|
947
|
+
];
|
|
948
|
+
case 2:
|
|
949
|
+
sourceId = (_b.sent()).enduserId;
|
|
950
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(sourceId)
|
|
951
|
+
// Cleanup
|
|
952
|
+
];
|
|
953
|
+
case 3:
|
|
954
|
+
updatedEnduser = _b.sent();
|
|
955
|
+
// Cleanup
|
|
956
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
957
|
+
case 4:
|
|
958
|
+
// Cleanup
|
|
959
|
+
_b.sent();
|
|
960
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(sourceId)
|
|
961
|
+
// eligibleForAutoMerge should be unset (undefined/falsy) after submission
|
|
962
|
+
];
|
|
963
|
+
case 5:
|
|
964
|
+
_b.sent();
|
|
965
|
+
// eligibleForAutoMerge should be unset (undefined/falsy) after submission
|
|
966
|
+
return [2 /*return*/, updatedEnduser.eligibleForAutoMerge !== true];
|
|
967
|
+
}
|
|
968
|
+
});
|
|
969
|
+
}); }, { expectedResult: true })
|
|
970
|
+
// ============================================
|
|
971
|
+
// BACKWARDS COMPATIBILITY & EDGE CASE TESTS
|
|
972
|
+
// ============================================
|
|
973
|
+
// Test 14: No merge when source enduser has multiple form responses
|
|
974
|
+
];
|
|
975
|
+
case 13:
|
|
976
|
+
// Test 13: eligibleForAutoMerge is unset after submission (no merge case)
|
|
977
|
+
_b.sent();
|
|
978
|
+
// ============================================
|
|
979
|
+
// BACKWARDS COMPATIBILITY & EDGE CASE TESTS
|
|
980
|
+
// ============================================
|
|
981
|
+
// Test 14: No merge when source enduser has multiple form responses
|
|
982
|
+
return [4 /*yield*/, async_test("Auto-merge: No merge when source enduser already has multiple form responses", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
983
|
+
var testEmail, destination, _a, form1, fields1, _b, form2, fields2, enduserSDK1, session1, sourceId, authedSDK1, fnameField1, lnameField1, emailField1, enduserSDK2, session2, sourceId2, authedSDK2, fnameField2, lnameField2, emailField2, sourceStillExists;
|
|
984
|
+
return __generator(this, function (_c) {
|
|
985
|
+
switch (_c.label) {
|
|
986
|
+
case 0:
|
|
987
|
+
testEmail = "automerge.multiresponse.".concat(Date.now(), "@test.com");
|
|
988
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
989
|
+
fname: 'Multi',
|
|
990
|
+
lname: 'Response',
|
|
991
|
+
email: testEmail
|
|
992
|
+
})];
|
|
993
|
+
case 1:
|
|
994
|
+
destination = _c.sent();
|
|
995
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
996
|
+
case 2:
|
|
997
|
+
_a = _c.sent(), form1 = _a.form, fields1 = _a.fields;
|
|
998
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)
|
|
999
|
+
// Create first public session and submit (this creates first form response)
|
|
1000
|
+
];
|
|
1001
|
+
case 3:
|
|
1002
|
+
_b = _c.sent(), form2 = _b.form, fields2 = _b.fields;
|
|
1003
|
+
enduserSDK1 = new EnduserSession({ host: host, businessId: form1.businessId });
|
|
1004
|
+
return [4 /*yield*/, enduserSDK1.api.form_responses.session_for_public_form({
|
|
1005
|
+
formId: form1.id,
|
|
1006
|
+
businessId: form1.businessId,
|
|
1007
|
+
skipMatch: true,
|
|
1008
|
+
})];
|
|
1009
|
+
case 4:
|
|
1010
|
+
session1 = _c.sent();
|
|
1011
|
+
sourceId = session1.enduserId;
|
|
1012
|
+
authedSDK1 = new EnduserSession({ host: host, businessId: form1.businessId, authToken: session1.authToken });
|
|
1013
|
+
fnameField1 = fields1.find(function (f) { return f.intakeField === 'fname'; });
|
|
1014
|
+
lnameField1 = fields1.find(function (f) { return f.intakeField === 'lname'; });
|
|
1015
|
+
emailField1 = fields1.find(function (f) { return f.intakeField === 'email'; });
|
|
1016
|
+
return [4 /*yield*/, authedSDK1.api.form_responses.submit_form_response({
|
|
1017
|
+
accessCode: session1.accessCode,
|
|
1018
|
+
responses: [
|
|
1019
|
+
{ fieldId: fnameField1.id, fieldTitle: fnameField1.title, answer: { type: 'string', value: 'Different' } },
|
|
1020
|
+
{ fieldId: lnameField1.id, fieldTitle: lnameField1.title, answer: { type: 'string', value: 'Person' } },
|
|
1021
|
+
{ fieldId: emailField1.id, fieldTitle: emailField1.title, answer: { type: 'email', value: "different.".concat(Date.now(), "@test.com") } },
|
|
1022
|
+
],
|
|
1023
|
+
})
|
|
1024
|
+
// Now create a second form response for the SAME source enduser via admin SDK
|
|
1025
|
+
];
|
|
1026
|
+
case 5:
|
|
1027
|
+
_c.sent();
|
|
1028
|
+
// Now create a second form response for the SAME source enduser via admin SDK
|
|
1029
|
+
return [4 /*yield*/, sdk.api.form_responses.createOne({
|
|
1030
|
+
formId: form2.id,
|
|
1031
|
+
formTitle: 'Auto Merge Test Form',
|
|
1032
|
+
enduserId: sourceId,
|
|
1033
|
+
})
|
|
1034
|
+
// Re-set eligibleForAutoMerge manually to simulate another attempt
|
|
1035
|
+
];
|
|
1036
|
+
case 6:
|
|
1037
|
+
// Now create a second form response for the SAME source enduser via admin SDK
|
|
1038
|
+
_c.sent();
|
|
1039
|
+
// Re-set eligibleForAutoMerge manually to simulate another attempt
|
|
1040
|
+
return [4 /*yield*/, sdk.api.endusers.updateOne(sourceId, { eligibleForAutoMerge: true })
|
|
1041
|
+
// Create another public session that would match - but source now has 2+ form responses
|
|
1042
|
+
];
|
|
1043
|
+
case 7:
|
|
1044
|
+
// Re-set eligibleForAutoMerge manually to simulate another attempt
|
|
1045
|
+
_c.sent();
|
|
1046
|
+
enduserSDK2 = new EnduserSession({ host: host, businessId: form2.businessId });
|
|
1047
|
+
return [4 /*yield*/, enduserSDK2.api.form_responses.session_for_public_form({
|
|
1048
|
+
formId: form2.id,
|
|
1049
|
+
businessId: form2.businessId,
|
|
1050
|
+
skipMatch: true,
|
|
1051
|
+
})];
|
|
1052
|
+
case 8:
|
|
1053
|
+
session2 = _c.sent();
|
|
1054
|
+
sourceId2 = session2.enduserId;
|
|
1055
|
+
// Manually add another form response to sourceId2 to trigger the >1 check
|
|
1056
|
+
return [4 /*yield*/, sdk.api.form_responses.createOne({
|
|
1057
|
+
formId: form1.id,
|
|
1058
|
+
formTitle: 'Auto Merge Test Form',
|
|
1059
|
+
enduserId: sourceId2,
|
|
1060
|
+
})
|
|
1061
|
+
// Submit with matching data - should NOT merge because source has >1 form responses
|
|
1062
|
+
];
|
|
1063
|
+
case 9:
|
|
1064
|
+
// Manually add another form response to sourceId2 to trigger the >1 check
|
|
1065
|
+
_c.sent();
|
|
1066
|
+
authedSDK2 = new EnduserSession({ host: host, businessId: form2.businessId, authToken: session2.authToken });
|
|
1067
|
+
fnameField2 = fields2.find(function (f) { return f.intakeField === 'fname'; });
|
|
1068
|
+
lnameField2 = fields2.find(function (f) { return f.intakeField === 'lname'; });
|
|
1069
|
+
emailField2 = fields2.find(function (f) { return f.intakeField === 'email'; });
|
|
1070
|
+
return [4 /*yield*/, authedSDK2.api.form_responses.submit_form_response({
|
|
1071
|
+
accessCode: session2.accessCode,
|
|
1072
|
+
responses: [
|
|
1073
|
+
{ fieldId: fnameField2.id, fieldTitle: fnameField2.title, answer: { type: 'string', value: 'Multi' } },
|
|
1074
|
+
{ fieldId: lnameField2.id, fieldTitle: lnameField2.title, answer: { type: 'string', value: 'Response' } },
|
|
1075
|
+
{ fieldId: emailField2.id, fieldTitle: emailField2.title, answer: { type: 'email', value: testEmail } },
|
|
1076
|
+
],
|
|
1077
|
+
})
|
|
1078
|
+
// Source should NOT be deleted because it had multiple form responses
|
|
1079
|
+
];
|
|
1080
|
+
case 10:
|
|
1081
|
+
_c.sent();
|
|
1082
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId2)];
|
|
1083
|
+
case 11:
|
|
1084
|
+
sourceStillExists = !(_c.sent());
|
|
1085
|
+
// Cleanup
|
|
1086
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form1.id)];
|
|
1087
|
+
case 12:
|
|
1088
|
+
// Cleanup
|
|
1089
|
+
_c.sent();
|
|
1090
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form2.id)];
|
|
1091
|
+
case 13:
|
|
1092
|
+
_c.sent();
|
|
1093
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
1094
|
+
case 14:
|
|
1095
|
+
_c.sent();
|
|
1096
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(sourceId)];
|
|
1097
|
+
case 15:
|
|
1098
|
+
_c.sent();
|
|
1099
|
+
if (!sourceStillExists) return [3 /*break*/, 17];
|
|
1100
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(sourceId2)];
|
|
1101
|
+
case 16:
|
|
1102
|
+
_c.sent();
|
|
1103
|
+
_c.label = 17;
|
|
1104
|
+
case 17: return [2 /*return*/, sourceStillExists];
|
|
1105
|
+
}
|
|
1106
|
+
});
|
|
1107
|
+
}); }, { expectedResult: true })
|
|
1108
|
+
// Test 15: Backwards compat - skipMatch=false does NOT set eligibleForAutoMerge
|
|
1109
|
+
];
|
|
1110
|
+
case 14:
|
|
1111
|
+
// ============================================
|
|
1112
|
+
// BACKWARDS COMPATIBILITY & EDGE CASE TESTS
|
|
1113
|
+
// ============================================
|
|
1114
|
+
// Test 14: No merge when source enduser has multiple form responses
|
|
1115
|
+
_b.sent();
|
|
1116
|
+
// Test 15: Backwards compat - skipMatch=false does NOT set eligibleForAutoMerge
|
|
1117
|
+
return [4 /*yield*/, async_test("Backwards compat: skipMatch=false does not set eligibleForAutoMerge even with autoMergeOnSubmission=true", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1118
|
+
var _a, form, fields, testPhone, enduserSDK, enduserId, enduser;
|
|
1119
|
+
return __generator(this, function (_b) {
|
|
1120
|
+
switch (_b.label) {
|
|
1121
|
+
case 0: return [4 /*yield*/, createAutoMergeForm(sdk, true)];
|
|
1122
|
+
case 1:
|
|
1123
|
+
_a = _b.sent(), form = _a.form, fields = _a.fields;
|
|
1124
|
+
testPhone = "+1555555".concat(Date.now().toString().slice(-4));
|
|
1125
|
+
enduserSDK = new EnduserSession({ host: host, businessId: form.businessId });
|
|
1126
|
+
return [4 /*yield*/, enduserSDK.api.form_responses.session_for_public_form({
|
|
1127
|
+
formId: form.id,
|
|
1128
|
+
businessId: form.businessId,
|
|
1129
|
+
phone: testPhone, // Phone is required when skipMatch is not set
|
|
1130
|
+
// skipMatch is NOT set (defaults to false)
|
|
1131
|
+
})];
|
|
1132
|
+
case 2:
|
|
1133
|
+
enduserId = (_b.sent()).enduserId;
|
|
1134
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(enduserId)
|
|
1135
|
+
// Cleanup
|
|
1136
|
+
];
|
|
1137
|
+
case 3:
|
|
1138
|
+
enduser = _b.sent();
|
|
1139
|
+
// Cleanup
|
|
1140
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
1141
|
+
case 4:
|
|
1142
|
+
// Cleanup
|
|
1143
|
+
_b.sent();
|
|
1144
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(enduserId)
|
|
1145
|
+
// eligibleForAutoMerge should NOT be set when skipMatch is false
|
|
1146
|
+
];
|
|
1147
|
+
case 5:
|
|
1148
|
+
_b.sent();
|
|
1149
|
+
// eligibleForAutoMerge should NOT be set when skipMatch is false
|
|
1150
|
+
return [2 /*return*/, enduser.eligibleForAutoMerge !== true];
|
|
1151
|
+
}
|
|
1152
|
+
});
|
|
1153
|
+
}); }, { expectedResult: true })
|
|
1154
|
+
// Test 16: Backwards compat - Private form submission doesn't trigger auto-merge
|
|
1155
|
+
];
|
|
1156
|
+
case 15:
|
|
1157
|
+
// Test 15: Backwards compat - skipMatch=false does NOT set eligibleForAutoMerge
|
|
1158
|
+
_b.sent();
|
|
1159
|
+
// Test 16: Backwards compat - Private form submission doesn't trigger auto-merge
|
|
1160
|
+
return [4 /*yield*/, async_test("Backwards compat: Private form submission does not trigger auto-merge", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1161
|
+
var testEmail, destination, source, _a, form, fields, fnameField, lnameField, emailField, sourceStillExists;
|
|
1162
|
+
return __generator(this, function (_b) {
|
|
1163
|
+
switch (_b.label) {
|
|
1164
|
+
case 0:
|
|
1165
|
+
testEmail = "backcompat.private.".concat(Date.now(), "@test.com");
|
|
1166
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
1167
|
+
fname: 'Private',
|
|
1168
|
+
lname: 'Test',
|
|
1169
|
+
email: testEmail
|
|
1170
|
+
})
|
|
1171
|
+
// Create source enduser with eligibleForAutoMerge manually set
|
|
1172
|
+
];
|
|
1173
|
+
case 1:
|
|
1174
|
+
destination = _b.sent();
|
|
1175
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
1176
|
+
fname: 'Private',
|
|
1177
|
+
lname: 'Test',
|
|
1178
|
+
email: testEmail + '.source',
|
|
1179
|
+
eligibleForAutoMerge: true, // Manually set to test that private submission ignores it
|
|
1180
|
+
})];
|
|
1181
|
+
case 2:
|
|
1182
|
+
source = _b.sent();
|
|
1183
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)
|
|
1184
|
+
// Create form response via admin SDK (private/non-public submission)
|
|
1185
|
+
];
|
|
1186
|
+
case 3:
|
|
1187
|
+
_a = _b.sent(), form = _a.form, fields = _a.fields;
|
|
1188
|
+
fnameField = fields.find(function (f) { return f.intakeField === 'fname'; });
|
|
1189
|
+
lnameField = fields.find(function (f) { return f.intakeField === 'lname'; });
|
|
1190
|
+
emailField = fields.find(function (f) { return f.intakeField === 'email'; });
|
|
1191
|
+
return [4 /*yield*/, sdk.api.form_responses.createOne({
|
|
1192
|
+
formId: form.id,
|
|
1193
|
+
formTitle: form.title,
|
|
1194
|
+
enduserId: source.id,
|
|
1195
|
+
responses: [
|
|
1196
|
+
{ fieldId: fnameField.id, fieldTitle: fnameField.title, answer: { type: 'string', value: 'Private' } },
|
|
1197
|
+
{ fieldId: lnameField.id, fieldTitle: lnameField.title, answer: { type: 'string', value: 'Test' } },
|
|
1198
|
+
{ fieldId: emailField.id, fieldTitle: emailField.title, answer: { type: 'email', value: testEmail } },
|
|
1199
|
+
],
|
|
1200
|
+
})
|
|
1201
|
+
// Source should NOT be deleted because this was a private submission (not publicSubmit)
|
|
1202
|
+
];
|
|
1203
|
+
case 4:
|
|
1204
|
+
_b.sent();
|
|
1205
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, source.id)];
|
|
1206
|
+
case 5:
|
|
1207
|
+
sourceStillExists = !(_b.sent());
|
|
1208
|
+
// Cleanup
|
|
1209
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
1210
|
+
case 6:
|
|
1211
|
+
// Cleanup
|
|
1212
|
+
_b.sent();
|
|
1213
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
1214
|
+
case 7:
|
|
1215
|
+
_b.sent();
|
|
1216
|
+
if (!sourceStillExists) return [3 /*break*/, 9];
|
|
1217
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(source.id)];
|
|
1218
|
+
case 8:
|
|
1219
|
+
_b.sent();
|
|
1220
|
+
_b.label = 9;
|
|
1221
|
+
case 9: return [2 /*return*/, sourceStillExists];
|
|
1222
|
+
}
|
|
1223
|
+
});
|
|
1224
|
+
}); }, { expectedResult: true })
|
|
1225
|
+
// Test 17: OR logic - matches on email even when phone differs
|
|
1226
|
+
];
|
|
1227
|
+
case 16:
|
|
1228
|
+
// Test 16: Backwards compat - Private form submission doesn't trigger auto-merge
|
|
1229
|
+
_b.sent();
|
|
1230
|
+
// Test 17: OR logic - matches on email even when phone differs
|
|
1231
|
+
return [4 /*yield*/, async_test("Auto-merge: Merge occurs when email matches even if phone differs (OR logic)", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1232
|
+
var testEmail, destination, _a, form, fields, sourceId, sourceDeleted, updatedDestination;
|
|
1233
|
+
var _b;
|
|
1234
|
+
return __generator(this, function (_c) {
|
|
1235
|
+
switch (_c.label) {
|
|
1236
|
+
case 0:
|
|
1237
|
+
testEmail = "automerge.orlogic.".concat(Date.now(), "@test.com");
|
|
1238
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
1239
|
+
fname: 'OrLogic',
|
|
1240
|
+
lname: 'Test',
|
|
1241
|
+
email: testEmail,
|
|
1242
|
+
phone: '+15555550001', // Different phone
|
|
1243
|
+
})];
|
|
1244
|
+
case 1:
|
|
1245
|
+
destination = _c.sent();
|
|
1246
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)
|
|
1247
|
+
// Submit with matching email but DIFFERENT phone
|
|
1248
|
+
];
|
|
1249
|
+
case 2:
|
|
1250
|
+
_a = _c.sent(), form = _a.form, fields = _a.fields;
|
|
1251
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
1252
|
+
fname: 'OrLogic',
|
|
1253
|
+
lname: 'Test',
|
|
1254
|
+
email: testEmail,
|
|
1255
|
+
phone: '+15555550002', // Different phone than destination
|
|
1256
|
+
})
|
|
1257
|
+
// Should merge because email matches (OR logic, not AND)
|
|
1258
|
+
];
|
|
1259
|
+
case 3:
|
|
1260
|
+
sourceId = (_c.sent()).enduserId;
|
|
1261
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)];
|
|
1262
|
+
case 4:
|
|
1263
|
+
sourceDeleted = _c.sent();
|
|
1264
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(destination.id)
|
|
1265
|
+
// Cleanup
|
|
1266
|
+
];
|
|
1267
|
+
case 5:
|
|
1268
|
+
updatedDestination = _c.sent();
|
|
1269
|
+
// Cleanup
|
|
1270
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
1271
|
+
case 6:
|
|
1272
|
+
// Cleanup
|
|
1273
|
+
_c.sent();
|
|
1274
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
1275
|
+
case 7:
|
|
1276
|
+
_c.sent();
|
|
1277
|
+
return [2 /*return*/, sourceDeleted && ((_b = updatedDestination.mergedIds) === null || _b === void 0 ? void 0 : _b.includes(sourceId))];
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
}); }, { expectedResult: true })
|
|
1281
|
+
// Test 18: Partial name mismatch - fname matches but lname differs
|
|
1282
|
+
];
|
|
1283
|
+
case 17:
|
|
1284
|
+
// Test 17: OR logic - matches on email even when phone differs
|
|
1285
|
+
_b.sent();
|
|
1286
|
+
// Test 18: Partial name mismatch - fname matches but lname differs
|
|
1287
|
+
return [4 /*yield*/, async_test("Auto-merge: No merge when fname matches but lname differs", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1288
|
+
var testEmail, destination, _a, form, fields, sourceId, sourceDeleted;
|
|
1289
|
+
return __generator(this, function (_b) {
|
|
1290
|
+
switch (_b.label) {
|
|
1291
|
+
case 0:
|
|
1292
|
+
testEmail = "automerge.partial.".concat(Date.now(), "@test.com");
|
|
1293
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
1294
|
+
fname: 'Partial',
|
|
1295
|
+
lname: 'Match',
|
|
1296
|
+
email: testEmail
|
|
1297
|
+
})];
|
|
1298
|
+
case 1:
|
|
1299
|
+
destination = _b.sent();
|
|
1300
|
+
return [4 /*yield*/, createAutoMergeForm(sdk, true)
|
|
1301
|
+
// Submit with same fname but DIFFERENT lname
|
|
1302
|
+
];
|
|
1303
|
+
case 2:
|
|
1304
|
+
_a = _b.sent(), form = _a.form, fields = _a.fields;
|
|
1305
|
+
return [4 /*yield*/, submitPublicFormWithSkipMatch(form, fields, {
|
|
1306
|
+
fname: 'Partial',
|
|
1307
|
+
lname: 'Different',
|
|
1308
|
+
email: testEmail, // Same email
|
|
1309
|
+
})
|
|
1310
|
+
// Should NOT merge because lname differs
|
|
1311
|
+
];
|
|
1312
|
+
case 3:
|
|
1313
|
+
sourceId = (_b.sent()).enduserId;
|
|
1314
|
+
return [4 /*yield*/, isEnduserDeleted(sdk, sourceId)
|
|
1315
|
+
// Cleanup
|
|
1316
|
+
];
|
|
1317
|
+
case 4:
|
|
1318
|
+
sourceDeleted = _b.sent();
|
|
1319
|
+
// Cleanup
|
|
1320
|
+
return [4 /*yield*/, sdk.api.forms.deleteOne(form.id)];
|
|
1321
|
+
case 5:
|
|
1322
|
+
// Cleanup
|
|
1323
|
+
_b.sent();
|
|
1324
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(destination.id)];
|
|
1325
|
+
case 6:
|
|
1326
|
+
_b.sent();
|
|
1327
|
+
if (!!sourceDeleted) return [3 /*break*/, 8];
|
|
1328
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(sourceId)];
|
|
1329
|
+
case 7:
|
|
1330
|
+
_b.sent();
|
|
1331
|
+
_b.label = 8;
|
|
1332
|
+
case 8: return [2 /*return*/, !sourceDeleted]; // Source should NOT be deleted
|
|
1333
|
+
}
|
|
1334
|
+
});
|
|
1335
|
+
}); }, { expectedResult: true })];
|
|
1336
|
+
case 18:
|
|
1337
|
+
// Test 18: Partial name mismatch - fname matches but lname differs
|
|
1338
|
+
_b.sent();
|
|
1339
|
+
return [2 /*return*/];
|
|
1340
|
+
}
|
|
1341
|
+
});
|
|
1342
|
+
});
|
|
1343
|
+
};
|
|
1344
|
+
// Allow running this test file independently
|
|
1345
|
+
if (require.main === module) {
|
|
1346
|
+
console.log("Using API URL: ".concat(host));
|
|
1347
|
+
var sdk_1 = new Session({ host: host });
|
|
1348
|
+
var sdkNonAdmin_1 = new Session({ host: host });
|
|
1349
|
+
var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1350
|
+
return __generator(this, function (_a) {
|
|
1351
|
+
switch (_a.label) {
|
|
1352
|
+
case 0: return [4 /*yield*/, setup_tests(sdk_1, sdkNonAdmin_1)];
|
|
1353
|
+
case 1:
|
|
1354
|
+
_a.sent();
|
|
1355
|
+
return [4 /*yield*/, auto_merge_form_submission_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
1356
|
+
case 2:
|
|
1357
|
+
_a.sent();
|
|
1358
|
+
return [2 /*return*/];
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
}); };
|
|
1362
|
+
runTests()
|
|
1363
|
+
.then(function () {
|
|
1364
|
+
console.log("Auto-merge form submission test suite completed successfully");
|
|
1365
|
+
process.exit(0);
|
|
1366
|
+
})
|
|
1367
|
+
.catch(function (error) {
|
|
1368
|
+
console.error("Auto-merge form submission test suite failed:", error);
|
|
1369
|
+
process.exit(1);
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
//# sourceMappingURL=auto_merge_form_submission.test.js.map
|