@tellescope/sdk 1.67.6 → 1.67.8

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.
@@ -655,6 +655,7 @@ const run_generated_tests = async <N extends ModelName>({ queries, model, name,
655
655
  || name === 'superbills'
656
656
  || name === 'referral_providers'
657
657
  || name === 'webhooks'
658
+ || name === 'automated_actions' // might process in background and cause false failure
658
659
  ) return
659
660
  if (!defaultEnduser) defaultEnduser = await sdk.api.endusers.createOne({ email: 'default@tellescope.com', phone: "5555555555" })
660
661
 
@@ -690,6 +691,7 @@ const run_generated_tests = async <N extends ModelName>({ queries, model, name,
690
691
  () => queries.createOne(instance),
691
692
  { onResult: r => !!(_id = r.id) && (name === 'api_keys' || !!r.creator) && validateReturnType(returns.create, r, defaultValidation) }
692
693
  )
694
+ await wait(undefined, 25)
693
695
  await async_test(
694
696
  `log-${singularName} create`,
695
697
  () => sdk.api.user_logs.getOne({ resourceId: _id, resource: name, action: 'create' }),
@@ -702,6 +704,7 @@ const run_generated_tests = async <N extends ModelName>({ queries, model, name,
702
704
  () => queries.updateOne(_id, updates, { replaceObjectFields: true }),
703
705
  { onResult: u => typeof u === 'object' && u.id === _id }
704
706
  )
707
+ await wait(undefined, 25)
705
708
  await async_test(
706
709
  `log-${singularName} update`,
707
710
  () => sdk.api.user_logs.getOne({ resourceId: _id, resource: name, action: 'update' }),
@@ -743,6 +746,7 @@ const run_generated_tests = async <N extends ModelName>({ queries, model, name,
743
746
  () => queries.deleteOne(_id),
744
747
  passOnVoid
745
748
  )
749
+ await wait(undefined, 25)
746
750
  await async_test(
747
751
  `get-${singularName} (verify delete)`,
748
752
  () => queries.getOne(_id),
@@ -1501,6 +1505,7 @@ const files_tests = async () => {
1501
1505
  const enduser = await sdk.api.endusers.createOne({ email })
1502
1506
  await sdk.api.endusers.set_password({ id: enduser.id, password }).catch(console.error)
1503
1507
  await enduserSDK.authenticate(email, password).catch(console.error)
1508
+ await sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword) // to use new role, handle logout on role change
1504
1509
 
1505
1510
  const buff = buffer.Buffer.from('test file data')
1506
1511
 
@@ -1933,12 +1938,16 @@ const ticketEventTests = async () => {
1933
1938
 
1934
1939
  await sdk.api.endusers.updateOne(enduser.id, { journeys: { [journey.id]: 'Added' }})
1935
1940
  await sdk.api.endusers.updateOne(enduserWithTeam.id, { journeys: { [nullJourney.id]: 'Added (Null)' }})
1936
- await wait(undefined, 2250) // wait for tickets to be automatically created
1937
1941
 
1938
1942
  await async_test(
1939
1943
  `Tickets automatically created`,
1940
- () => sdk.api.tickets.getSome(),
1941
- { onResult: tickets => tickets?.length === 2 }
1944
+ () => pollForResults(
1945
+ sdk.api.tickets.getSome,
1946
+ tickets => tickets?.length === 2,
1947
+ 500,
1948
+ 15,
1949
+ ),
1950
+ passOnAnyResult
1942
1951
  )
1943
1952
 
1944
1953
  await async_test(
@@ -2050,11 +2059,15 @@ const removeFromJourneyTests = async () => {
2050
2059
  { onResult: e => e.journeys?.[journey.id] !== 'Delayed Step' }
2051
2060
  )
2052
2061
 
2053
- await wait(undefined, 4 * TEST_DELAY) // wait long enough for automation to process and delay to pass
2054
2062
  await async_test(
2055
2063
  `Sequenced action triggered`,
2056
- () => sdk.api.endusers.getOne(enduser.id),
2057
- { onResult: e => e.journeys?.[journey.id] === 'Delayed Step' }
2064
+ () => pollForResults(
2065
+ () => sdk.api.endusers.getOne(enduser.id),
2066
+ e => e.journeys?.[journey.id] === 'Delayed Step',
2067
+ TEST_DELAY,
2068
+ 15,
2069
+ ),
2070
+ passOnAnyResult
2058
2071
  )
2059
2072
 
2060
2073
  await Promise.all([
@@ -2238,11 +2251,15 @@ export const formUnsubmittedCancelConditionTest = async () => {
2238
2251
  })
2239
2252
 
2240
2253
  // allow fast followup to trigger
2241
- await wait(undefined, 4000) // allow background creation with generous pause
2242
2254
  await async_test(
2243
2255
  `formUnsubmitted event with short delay is triggered`,
2244
- () => sdk.api.endusers.getOne(enduser.id),
2245
- { onResult: e => e?.journeys?.[journey.id] === 'triggered again' }
2256
+ () => pollForResults(
2257
+ () => sdk.api.endusers.getOne(enduser.id),
2258
+ e => e?.journeys?.[journey.id] === 'triggered again',
2259
+ 1000,
2260
+ 10,
2261
+ ),
2262
+ passOnAnyResult
2246
2263
  )
2247
2264
 
2248
2265
  // trigger cancel conditions
@@ -2431,8 +2448,13 @@ export const formsUnsubmittedCancelConditionTest = async () => {
2431
2448
  )
2432
2449
  await async_test(
2433
2450
  `formResponses triggered after both forms submitted`,
2434
- () => sdk.api.endusers.getOne(enduser.id),
2435
- { onResult: e => e?.journeys?.[journey.id] === 'formsSubmitted' }
2451
+ () => pollForResults(
2452
+ () => sdk.api.endusers.getOne(enduser.id),
2453
+ e => e?.journeys?.[journey.id] === 'formsSubmitted',
2454
+ 500,
2455
+ 10,
2456
+ ),
2457
+ passOnAnyResult
2436
2458
  )
2437
2459
 
2438
2460
  await Promise.all([
@@ -2509,13 +2531,15 @@ export const formsUnsubmittedTest = async () => {
2509
2531
 
2510
2532
  const form_responses = await sdk.api.form_responses.getSome()
2511
2533
 
2512
- // allow fast followup to trigger
2513
- await wait(undefined, 5000) // allow background creation with generous pause
2514
-
2515
2534
  await async_test(
2516
2535
  `formsUnsubmitted handler worked`,
2517
- () => sdk.api.endusers.getOne(enduser.id),
2518
- { onResult: e => e?.journeys?.[journey.id] === 'triggered' }
2536
+ () => pollForResults(
2537
+ () => sdk.api.endusers.getOne(enduser.id),
2538
+ e => e?.journeys?.[journey.id] === 'triggered',
2539
+ 1000,
2540
+ 10
2541
+ ),
2542
+ passOnAnyResult,
2519
2543
  )
2520
2544
 
2521
2545
  // trigger cancel conditions
@@ -2723,27 +2747,37 @@ const addToJourneyTests = async () => {
2723
2747
  { onResult: e => e.journeys?.[journey.id] === '' || e.journeys?.[journey.id] === 'Root' }
2724
2748
  )
2725
2749
 
2726
- await wait(undefined, 4000) // allow onJourneyStart step to trigger
2750
+ // ensure that second step is generated before first is cancelled
2751
+ await pollForResults(
2752
+ sdk.api.automated_actions.getSome,
2753
+ es => es.length === 2,
2754
+ 100,
2755
+ 50,
2756
+ ),
2757
+
2727
2758
  await sdk.api.endusers.add_to_journey({ enduserIds: [enduser.id], journeyId: journey.id })
2728
2759
 
2760
+ await async_test(
2761
+ `Enduser correctly added and re-added`,
2762
+ () => pollForResults(
2763
+ sdk.api.automated_actions.getSome,
2764
+ es => (es.length === 4
2765
+ && es.filter(e => e.status === 'cancelled' && e.automationStepId === follow.id).length === 1 // one afterAction is cancelled
2766
+ && es.filter(e => e.status === 'active' && e.automationStepId === follow.id).length === 1 // one afterAction is still active
2767
+ && es.filter(e => e.status === 'finished' && e.automationStepId === root.id).length === 2 // two initial onJourneyStart
2768
+ ),
2769
+ 250,
2770
+ 40
2771
+ ),
2772
+ passOnAnyResult
2773
+ )
2774
+
2729
2775
  await async_test(
2730
2776
  `Enduser throttle journey add working`,
2731
2777
  () => sdk.api.endusers.add_to_journey({ enduserIds: [enduser.id], journeyId: journey.id, throttle: true }),
2732
2778
  handleAnyError
2733
2779
  )
2734
2780
 
2735
- await wait(undefined, 4000) // allow onJourneyStart step to trigger
2736
-
2737
- await async_test(
2738
- `Enduser correctly added and re-added`,
2739
- () => sdk.api.automated_actions.getSome(),
2740
- { onResult: es => es.length === 4
2741
- && es.filter(e => e.status === 'cancelled' && e.automationStepId === follow.id).length === 1 // one afterAction is cancelled
2742
- && es.filter(e => e.status === 'active' && e.automationStepId === follow.id).length === 1 // one afterAction is still active
2743
- && es.filter(e => e.status === 'finished' && e.automationStepId === root.id).length === 2 // two initial onJourneyStart
2744
- }
2745
- )
2746
-
2747
2781
  await Promise.all([
2748
2782
  sdk.api.journeys.deleteOne(journey.id),
2749
2783
  sdk.api.endusers.deleteOne(enduser.id),
@@ -4204,7 +4238,9 @@ export const role_based_access_permissions_tests = async () => {
4204
4238
  }
4205
4239
  }
4206
4240
  })
4207
- await sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { roles: [noEnduserAccessRole] }, { replaceObjectFields: true }),
4241
+ const sdkNonAdminId = sdkNonAdmin.userInfo.id
4242
+
4243
+ await sdk.api.users.updateOne(sdkNonAdminId, { roles: [noEnduserAccessRole] }, { replaceObjectFields: true }),
4208
4244
  await sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword) // to use new role, handle logout on role change
4209
4245
 
4210
4246
  await async_test(
@@ -4250,10 +4286,8 @@ export const role_based_access_permissions_tests = async () => {
4250
4286
  )
4251
4287
 
4252
4288
  // cleanup
4253
- await Promise.all([
4254
- sdk.api.role_based_access_permissions.deleteOne(rbap.id),
4255
- sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { roles: ['Non-Admin'] }, { replaceObjectFields: true }),
4256
- ])
4289
+ await sdk.api.role_based_access_permissions.deleteOne(rbap.id)
4290
+ await sdk.api.users.updateOne(sdkNonAdminId, { roles: ['Non-Admin'] }, { replaceObjectFields: true })
4257
4291
  await sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword) // to use new role, handle logout on role change
4258
4292
  }
4259
4293
 
@@ -4280,15 +4314,19 @@ const run_autoreply_test = async (title: string, { expectingAutoreply } : { expe
4280
4314
  )
4281
4315
 
4282
4316
  await enduserSDK.api.chats.createOne({ roomId: room.id, message: 'enduser' })
4283
- await wait (undefined, 50)
4284
4317
  await async_test(
4285
4318
  'Main test',
4286
- () => sdk.api.chats.getSome({ filter: { roomId: room.id }}),
4287
- { onResult: cs => (
4288
- expectingAutoreply
4289
- ? cs.length === 3
4290
- : cs.length === 2
4291
- ) }
4319
+ () => pollForResults(
4320
+ () => sdk.api.chats.getSome({ filter: { roomId: room.id }}),
4321
+ cs => (
4322
+ expectingAutoreply
4323
+ ? cs.length === 3
4324
+ : cs.length === 2
4325
+ ),
4326
+ 25,
4327
+ 10
4328
+ ),
4329
+ passOnAnyResult
4292
4330
  )
4293
4331
 
4294
4332
  await enduserSDK.api.chats.createOne({ roomId: room.id, message: 'enduser again' })
@@ -4605,11 +4643,15 @@ const wait_for_trigger_tests = async () => {
4605
4643
  ])
4606
4644
 
4607
4645
  // test trigger cleaned up on journey delete
4608
- await wait(undefined, 150)
4609
4646
  await async_test(
4610
- "Trigger did not fire while not journey",
4611
- () => sdk.api.automation_triggers.getOne(trigger.id),
4612
- handleAnyError
4647
+ "Trigger cleaned up by journey deletion",
4648
+ () => pollForResults(
4649
+ sdk.api.automation_triggers.getSome,
4650
+ results => !results.find(r => r.id === trigger.id),
4651
+ 100,
4652
+ 10,
4653
+ ),
4654
+ passOnAnyResult
4613
4655
  )
4614
4656
 
4615
4657
  // double-check that wait for trigger step triggers were deleted
@@ -4757,38 +4799,41 @@ const remove_from_journey_on_incoming_comms_tests = async () => {
4757
4799
 
4758
4800
  const room = await sdk.api.chat_rooms.createOne({ })
4759
4801
  await sdk.api.chats.createOne({ roomId: room.id, senderId: e1.id, message: 'cancel' })
4760
- await wait(undefined, 100)
4761
4802
 
4762
- console.log(jRemove.id, removeStep2.id, e1.id)
4763
4803
  await async_test(
4764
4804
  "Appropriate Automated Actions are cancelled on incoming message",
4765
- () => sdk.api.automated_actions.getSome(),
4766
- { onResult: actions => (
4767
- !!actions.find(a =>
4805
+ () => pollForResults(
4806
+ sdk.api.automated_actions.getSome,
4807
+ actions => (
4808
+ !!actions.find(a =>
4809
+ a.journeyId === jRemove.id
4810
+ && a.automationStepId === removeStep1.id
4811
+ && a.enduserId === e1.id
4812
+ && a.status === 'cancelled'
4813
+ )
4814
+ && !!actions.find(a =>
4768
4815
  a.journeyId === jRemove.id
4769
4816
  && a.automationStepId === removeStep1.id
4817
+ && a.enduserId === e2.id
4818
+ && a.status === 'active'
4819
+ )
4820
+ && !!actions.find(a =>
4821
+ a.journeyId === jDontRemove.id
4822
+ && a.automationStepId === dontRemoveStep1.id
4770
4823
  && a.enduserId === e1.id
4771
- && a.status === 'cancelled'
4824
+ && a.status === 'active'
4772
4825
  )
4773
- && !!actions.find(a =>
4774
- a.journeyId === jRemove.id
4775
- && a.automationStepId === removeStep1.id
4776
- && a.enduserId === e2.id
4777
- && a.status === 'active'
4778
- )
4779
- && !!actions.find(a =>
4780
- a.journeyId === jDontRemove.id
4781
- && a.automationStepId === dontRemoveStep1.id
4782
- && a.enduserId === e1.id
4783
- && a.status === 'active'
4784
- )
4785
- && !!actions.find(a =>
4786
- a.journeyId === jDontRemove.id
4787
- && a.automationStepId === dontRemoveStep1.id
4788
- && a.enduserId === e2.id
4789
- && a.status === 'active'
4790
- )
4791
- )}
4826
+ && !!actions.find(a =>
4827
+ a.journeyId === jDontRemove.id
4828
+ && a.automationStepId === dontRemoveStep1.id
4829
+ && a.enduserId === e2.id
4830
+ && a.status === 'active'
4831
+ )
4832
+ ),
4833
+ 100,
4834
+ 50,
4835
+ ),
4836
+ passOnAnyResult,
4792
4837
  )
4793
4838
 
4794
4839
  await sdk.api.journeys.handle_incoming_communication({ enduserId: e2.id })
@@ -4816,6 +4861,8 @@ const remove_from_journey_on_incoming_comms_tests = async () => {
4816
4861
  }
4817
4862
 
4818
4863
  const pdf_generation = async () => {
4864
+ log_header("pdf_generation Tests")
4865
+
4819
4866
  const e = await sdk.api.endusers.createOne({ fname: 'test' })
4820
4867
 
4821
4868
  // include lots of answers to ensure PDF height doesn't produce any cut-off
@@ -4850,7 +4897,6 @@ const pdf_generation = async () => {
4850
4897
 
4851
4898
  await Promise.all([
4852
4899
  sdk.api.endusers.deleteOne(e.id),
4853
- sdk.api.form_responses.deleteOne(fr.id),
4854
4900
  ])
4855
4901
  }
4856
4902
 
@@ -5033,12 +5079,15 @@ const nextReminderInMS_tests = async () => {
5033
5079
  }
5034
5080
 
5035
5081
  const pollForResults = async <T>(f: () => Promise<T>, evaluate: (r: T) => boolean, intervalInMS=500, iterations=20) => {
5082
+ let lastResult = undefined as any
5036
5083
  for (let i = 0; i < iterations; i++) {
5037
5084
  await wait(undefined, intervalInMS)
5038
5085
  const result = await f()
5086
+ lastResult = result
5039
5087
  if (evaluate(result)) return result
5040
5088
  }
5041
5089
 
5090
+ console.log(lastResult)
5042
5091
  throw new Error("failed pollForResults")
5043
5092
  }
5044
5093
 
Binary file