@tellescope/sdk 1.201.0 → 1.203.0

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.
@@ -37,7 +37,7 @@ import {
37
37
  } from "@tellescope/validation"
38
38
 
39
39
  import { Session, APIQuery, EnduserSession } from "../sdk"
40
- import { FORM_LOGIC_CALCULATED_FIELDS, get_care_team_primary, get_flattened_fields, replace_enduser_template_values, responses_satisfy_conditions, weighted_round_robin, YYYY_MM_DD_to_MM_DD_YYYY } from "@tellescope/utilities"
40
+ import { evaluate_conditional_logic_for_enduser_fields, FORM_LOGIC_CALCULATED_FIELDS, get_care_team_primary, get_flattened_fields, replace_enduser_template_values, responses_satisfy_conditions, weighted_round_robin, YYYY_MM_DD_to_MM_DD_YYYY } from "@tellescope/utilities"
41
41
  import { DEFAULT_OPERATIONS, PLACEHOLDER_ID, ZOOM_TITLE } from "@tellescope/constants"
42
42
  import {
43
43
  schema,
@@ -7298,22 +7298,24 @@ export const formsort_tests = async () => {
7298
7298
 
7299
7299
  const form = await sdk.api.forms.createOne({ title: "FormSort" })
7300
7300
 
7301
- const postToFormsort = async ({ matchByName=false, ...o }: {
7301
+ const postToFormsort = async ({ matchByName=false, createNewEnduser=false, ...o }: {
7302
7302
  answers: { key: string, value: any }[],
7303
7303
  responder_uuid: string,
7304
7304
  finalized: boolean,
7305
7305
  matchByName?: boolean,
7306
+ createNewEnduser?: boolean,
7306
7307
  }) => {
7307
- await axios.post(`${host}/v1/webhooks/formsort/9d4f9dff00f60df2690a16da2cb848f289b447614ad9bef850e54af09a1fbf7a?formId=${form.id}&matchByName=${matchByName}`, o)
7308
+ await axios.post(`${host}/v1/webhooks/formsort/9d4f9dff00f60df2690a16da2cb848f289b447614ad9bef850e54af09a1fbf7a?formId=${form.id}&matchByName=${matchByName}&createNewEnduser=${createNewEnduser}`, o)
7308
7309
  }
7309
7310
 
7310
- const postToFormsortGeneric = async ({ matchByName=false, ...o }: {
7311
+ const postToFormsortGeneric = async ({ matchByName=false, createNewEnduser=false, ...o }: {
7311
7312
  answers: { key: string, value: any }[],
7312
7313
  responder_uuid: string,
7313
7314
  finalized: boolean,
7314
7315
  matchByName?: boolean,
7316
+ createNewEnduser?: boolean,
7315
7317
  }) => {
7316
- await axios.post(`${host}/v1/webhooks/form-ingestion/9d4f9dff00f60df2690a16da2cb848f289b447614ad9bef850e54af09a1fbf7a?formId=${form.id}&matchByName=${matchByName}`, o)
7318
+ await axios.post(`${host}/v1/webhooks/form-ingestion/9d4f9dff00f60df2690a16da2cb848f289b447614ad9bef850e54af09a1fbf7a?formId=${form.id}&matchByName=${matchByName}&createNewEnduser=${createNewEnduser}`, o)
7317
7319
  }
7318
7320
 
7319
7321
  const emailAnswer = { key: 'email', value: 'test@tellescope.com' }
@@ -7520,6 +7522,28 @@ export const formsort_tests = async () => {
7520
7522
  }
7521
7523
  )
7522
7524
 
7525
+ await postToFormsort({ answers: [emailAnswer], responder_uuid: "createNewEnduser", finalized: false, createNewEnduser: true })
7526
+ await async_test(`new enduser and form response created (1)`, sdk.api.form_responses.getSome, { onResult: r => r.length === 7 })
7527
+ await async_test(`new enduser and form response created (1)`, sdk.api.endusers.getSome, { onResult: r => r.length === 5 })
7528
+
7529
+ await postToFormsort({ answers: [emailAnswer], responder_uuid: "createNewEnduser", finalized: false, createNewEnduser: true })
7530
+ await async_test(`new enduser and form response created (2)`, sdk.api.form_responses.getSome, {
7531
+ onResult: r => r.length === 8 && r.filter(e => e.externalId === 'createNewEnduser').length === 2
7532
+ })
7533
+ await async_test(`new enduser and form response created (2)`, sdk.api.endusers.getSome, {
7534
+ onResult: r => r.length === 6 && r.filter(e => e.externalId === 'createNewEnduser').length === 2
7535
+ })
7536
+
7537
+ await postToFormsort({ answers: [emailAnswer], responder_uuid: "createNewEnduser", finalized: true, createNewEnduser: true })
7538
+ await async_test(`new enduser and form response created (3, finalized)`, sdk.api.form_responses.getSome, {
7539
+ onResult: r => r.length === 9 && r.filter(e => e.externalId === 'createNewEnduser').length === 3
7540
+ })
7541
+ await async_test(`new enduser and form response created (3, finalized)`, sdk.api.endusers.getSome, {
7542
+ onResult: r => r.length === 7
7543
+ && r.filter(e => e.externalId === 'createNewEnduser').length === 3
7544
+ && r.filter(e => e.externalId === 'createNewEnduser' && e.email === emailAnswer.value).length === 1 // email set on finalized
7545
+ })
7546
+
7523
7547
  // cleanup
7524
7548
  const endusers = await sdk.api.endusers.getSome()
7525
7549
  await Promise.all([
@@ -8272,6 +8296,140 @@ export const form_conditional_logic_tests = async () => {
8272
8296
  run_conditional_form_test({ $and: [{ condition: { [FORM_LOGIC_CALCULATED_FIELDS[0]]: { $lt: 25 } } }] }, false)
8273
8297
  }
8274
8298
 
8299
+ export const enduser_conditional_logic_tests = async () => {
8300
+ log_header("Enduser Conditional Logic Tests")
8301
+
8302
+ const requiredPlaceholders = {
8303
+ businessId: '', creator: '', hashedPassword: '', lastActive: '', lastLogout: '', updatedAt: new Date(),
8304
+ }
8305
+
8306
+ assert(
8307
+ evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [] }, { }),
8308
+ 'Conditional logic error',
8309
+ 'blank upcoming events with blank condition',
8310
+ )
8311
+
8312
+ assert(
8313
+ evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [] }, { "$and": [] }),
8314
+ 'Conditional logic error',
8315
+ 'blank upcoming events with empty and condition',
8316
+ )
8317
+
8318
+ assert(
8319
+ evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [] }, {
8320
+ "$and": [{ "condition": { "__upcomingEvents__": { "$lt": "1", "$fromOffset": -3600000, "$toOffset": 3600000 }}}]
8321
+ }),
8322
+ 'Conditional logic error',
8323
+ 'blank upcoming events with less than 1 condition',
8324
+ )
8325
+
8326
+ assert(
8327
+ !evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [] }, {
8328
+ "$and": [{ "condition": { "__upcomingEvents__": { "$lt": "0", "$fromOffset": -3600000, "$toOffset": 3600000 }}}]
8329
+ }),
8330
+ 'Conditional logic error',
8331
+ 'blank upcoming events with less than 0 condition',
8332
+ )
8333
+
8334
+ assert(
8335
+ !evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [] }, {
8336
+ "$and": [{ "condition": { "__upcomingEvents__": { "$gt": "0", "$fromOffset": -3600000, "$toOffset": 3600000 }}}]
8337
+ }),
8338
+ 'Conditional logic error',
8339
+ 'blank upcoming events with greater than 0 condition',
8340
+ )
8341
+
8342
+ assert(
8343
+ !evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [{ startTimeInMS: Date.now() - 10000 }] }, {
8344
+ "$and": [{ "condition": { "__upcomingEvents__": { "$gt": "0" }}}]
8345
+ }),
8346
+ 'Conditional logic error',
8347
+ 'past events are ignored by default (no $fromOffset set)',
8348
+ )
8349
+
8350
+ assert(
8351
+ evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [{ startTimeInMS: Date.now() + 10000 }] }, {
8352
+ "$and": [{ "condition": { "__upcomingEvents__": { "$gt": "0" }}}]
8353
+ }),
8354
+ 'Conditional logic error',
8355
+ 'future events are recognized by default (no $fromOffset set)',
8356
+ )
8357
+
8358
+ assert(
8359
+ !evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [{ startTimeInMS: Date.now() - 100000 }] }, {
8360
+ "$and": [{ "condition": { "__upcomingEvents__": { "$gt": "0", "$fromOffset": -10000, "$toOffset": 3600000 }}}]
8361
+ }),
8362
+ 'Conditional logic error',
8363
+ 'Past event outside of window',
8364
+ )
8365
+
8366
+ assert(
8367
+ evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [{ startTimeInMS: Date.now() - 100 }] }, {
8368
+ "$and": [{ "condition": { "__upcomingEvents__": { "$gt": "0", "$fromOffset": -10000, "$toOffset": 3600000 }}}]
8369
+ }),
8370
+ 'Conditional logic error',
8371
+ 'Past event inside of window',
8372
+ )
8373
+
8374
+ assert(
8375
+ !evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [{ startTimeInMS: Date.now() + 1000000 }] }, {
8376
+ "$and": [{ "condition": { "__upcomingEvents__": { "$gt": "0", "$fromOffset": -10000, "$toOffset": 10000 }}}]
8377
+ }),
8378
+ 'Conditional logic error',
8379
+ 'Future event outside of window',
8380
+ )
8381
+
8382
+ assert(
8383
+ evaluate_conditional_logic_for_enduser_fields({ ...requiredPlaceholders, _upcomingEvents: [{ startTimeInMS: Date.now() + 100 }] }, {
8384
+ "$and": [{ "condition": { "__upcomingEvents__": { "$gt": "0", "$fromOffset": -10000, "$toOffset": 10000 }}}]
8385
+ }),
8386
+ 'Conditional logic error',
8387
+ 'Future event inside of window',
8388
+ )
8389
+ }
8390
+
8391
+ export const cancel_upcoming_appointments_journey_action_test = async () => {
8392
+ log_header("Cancel Upcoming Appointments Journey Action Test")
8393
+
8394
+ const enduser = await sdk.api.endusers.createOne({ })
8395
+ const e1 = await sdk.api.calendar_events.createOne({ title: 'past', startTimeInMS: Date.now() - 100000, durationInMinutes: 60, attendees: [{ type: 'enduser', id: enduser.id }] })
8396
+ const e2 = await sdk.api.calendar_events.createOne({ title: 'future', startTimeInMS: Date.now() + 100000, durationInMinutes: 60, attendees: [{ type: 'enduser', id: enduser.id }]})
8397
+ const e3 = await sdk.api.calendar_events.createOne({ title: 'past, not enduser', startTimeInMS: Date.now() + 100000, durationInMinutes: 60 })
8398
+ const e4 = await sdk.api.calendar_events.createOne({ title: 'future, not enduser', startTimeInMS: Date.now() + 100000, durationInMinutes: 60 })
8399
+
8400
+ await sdk.api.automated_actions.createOne({
8401
+ automationStepId: PLACEHOLDER_ID, journeyId: PLACEHOLDER_ID,
8402
+ processAfter: 0, status: 'active',
8403
+ enduserId: enduser.id,
8404
+ event: { type: 'onJourneyStart', info: {} },
8405
+ action: { type: 'cancelFutureAppointments', info: {} },
8406
+ })
8407
+
8408
+ await async_test(
8409
+ `Upcoming event is cancelled, past appointment is not`,
8410
+ () => pollForResults(
8411
+ sdk.api.calendar_events.getSome,
8412
+ es => (
8413
+ !!es.find(e => e.id === e1.id && !e.cancelledAt) // past event should not be cancelled
8414
+ && !!es.find(e => e.id === e2.id && !!e.cancelledAt) // future event should be cancelled
8415
+ && !!es.find(e => e.id === e3.id && !e.cancelledAt) // past event not enduser should not be cancelled
8416
+ && !!es.find(e => e.id === e4.id && !e.cancelledAt) // future event not enduser should not be cancelled
8417
+ ),
8418
+ 50,
8419
+ 100,
8420
+ ),
8421
+ passOnAnyResult
8422
+ )
8423
+
8424
+ await Promise.all([
8425
+ sdk.api.endusers.deleteOne(enduser.id),
8426
+ sdk.api.calendar_events.deleteOne(e1.id),
8427
+ sdk.api.calendar_events.deleteOne(e2.id),
8428
+ sdk.api.calendar_events.deleteOne(e3.id),
8429
+ sdk.api.calendar_events.deleteOne(e4.id),
8430
+ ])
8431
+ }
8432
+
8275
8433
  export const ticket_reminder_tests = async () => {
8276
8434
  log_header("Ticket Reminder Tests")
8277
8435
 
@@ -11356,10 +11514,13 @@ const inbox_loading_tests = async () => {
11356
11514
  )
11357
11515
 
11358
11516
 
11517
+ await enduser_conditional_logic_tests()
11359
11518
  await replace_enduser_template_values_tests()
11360
11519
  await mfa_tests()
11361
11520
  await setup_tests()
11521
+ await formsort_tests()
11362
11522
  await inbox_loading_tests()
11523
+ await cancel_upcoming_appointments_journey_action_test()
11363
11524
  await multi_tenant_tests() // should come right after setup tests
11364
11525
  await sync_tests_with_access_tags() // should come directly after setup to avoid extra sync values
11365
11526
  await sync_tests() // should come directly after setup to avoid extra sync values
@@ -11378,7 +11539,6 @@ const inbox_loading_tests = async () => {
11378
11539
  await calendar_event_care_team_tests()
11379
11540
  await merge_enduser_tests()
11380
11541
  await input_modifier_tests()
11381
- await formsort_tests()
11382
11542
  await switch_to_related_contacts_tests()
11383
11543
  await redaction_tests()
11384
11544
  await self_serve_appointment_booking_tests()
Binary file