@tellescope/sdk 1.3.42 → 1.3.43
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/tests/tests.d.ts +1 -0
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +250 -18
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/cjs/tests/webhooks_tests.js +4 -4
- package/lib/cjs/tests/webhooks_tests.js.map +1 -1
- package/lib/esm/tests/tests.d.ts +1 -0
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +248 -17
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/esm/tests/webhooks_tests.js +4 -4
- package/lib/esm/tests/webhooks_tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/tests/tests.ts +194 -11
- package/src/tests/webhooks_tests.ts +4 -4
package/src/tests/tests.ts
CHANGED
|
@@ -1550,7 +1550,7 @@ const formEventTests = async () => {
|
|
|
1550
1550
|
|
|
1551
1551
|
const triggerStep = await sdk.api.automation_steps.createOne({
|
|
1552
1552
|
journeyId: journey.id,
|
|
1553
|
-
|
|
1553
|
+
events: [{ type: 'onJourneyStart', info: { } }],
|
|
1554
1554
|
// in practice, this would send a form, so that the next step(s) could handle the response
|
|
1555
1555
|
// but we don't want to send emails in testing, and can still attach this Id to a form response to test a trigger
|
|
1556
1556
|
action: {
|
|
@@ -1560,10 +1560,10 @@ const formEventTests = async () => {
|
|
|
1560
1560
|
})
|
|
1561
1561
|
await sdk.api.automation_steps.createOne({
|
|
1562
1562
|
journeyId: journey.id,
|
|
1563
|
-
|
|
1563
|
+
events: [{
|
|
1564
1564
|
type: 'formResponse',
|
|
1565
1565
|
info: { automationStepId: triggerStep.id }
|
|
1566
|
-
},
|
|
1566
|
+
}],
|
|
1567
1567
|
action: {
|
|
1568
1568
|
type: 'setEnduserStatus',
|
|
1569
1569
|
info: { status: 'placeholder' },
|
|
@@ -1614,7 +1614,7 @@ const ticketEventTests = async () => {
|
|
|
1614
1614
|
|
|
1615
1615
|
const root = await sdk.api.automation_steps.createOne({
|
|
1616
1616
|
journeyId: journey.id,
|
|
1617
|
-
|
|
1617
|
+
events: [{ type: 'onJourneyStart', info: { } }],
|
|
1618
1618
|
action: {
|
|
1619
1619
|
type: 'createTicket',
|
|
1620
1620
|
info: {
|
|
@@ -1630,7 +1630,7 @@ const ticketEventTests = async () => {
|
|
|
1630
1630
|
})
|
|
1631
1631
|
const nullRoot = await sdk.api.automation_steps.createOne({
|
|
1632
1632
|
journeyId: nullJourney.id,
|
|
1633
|
-
|
|
1633
|
+
events: [{ type: 'onJourneyStart', info: { } }],
|
|
1634
1634
|
action: {
|
|
1635
1635
|
type: 'createTicket',
|
|
1636
1636
|
info: {
|
|
@@ -1648,7 +1648,7 @@ const ticketEventTests = async () => {
|
|
|
1648
1648
|
const createStep = (journeyId: string, automationStepId: string, closedForReason?: string ) => (
|
|
1649
1649
|
sdk.api.automation_steps.createOne({
|
|
1650
1650
|
journeyId,
|
|
1651
|
-
|
|
1651
|
+
events: [{ type: 'ticketCompleted', info: { automationStepId, closedForReason, } }],
|
|
1652
1652
|
action: { type: 'setEnduserStatus', info: { status: closedForReason ?? 'Null' }, },
|
|
1653
1653
|
})
|
|
1654
1654
|
)
|
|
@@ -1664,7 +1664,7 @@ const ticketEventTests = async () => {
|
|
|
1664
1664
|
|
|
1665
1665
|
await sdk.api.endusers.updateOne(enduser.id, { journeys: { [journey.id]: 'Added' }})
|
|
1666
1666
|
await sdk.api.endusers.updateOne(enduserWithTeam.id, { journeys: { [nullJourney.id]: 'Added (Null)' }})
|
|
1667
|
-
await wait(undefined,
|
|
1667
|
+
await wait(undefined, 2200) // wait for tickets to be automatically created
|
|
1668
1668
|
|
|
1669
1669
|
await async_test(
|
|
1670
1670
|
`Tickets automatically created`,
|
|
@@ -1733,6 +1733,70 @@ const ticketEventTests = async () => {
|
|
|
1733
1733
|
const removeFromJourneyTests = async () => {
|
|
1734
1734
|
log_header("Remove from Journey")
|
|
1735
1735
|
|
|
1736
|
+
const journey = await sdk.api.journeys.createOne({ title: 'test journey'})
|
|
1737
|
+
const enduser = await sdk.api.endusers.createOne({ email: 'test@tellescope.com' })
|
|
1738
|
+
|
|
1739
|
+
const TEST_DELAY = 1000
|
|
1740
|
+
|
|
1741
|
+
const step = await (
|
|
1742
|
+
sdk.api.automation_steps.createOne({
|
|
1743
|
+
journeyId: journey.id,
|
|
1744
|
+
events: [{ type: 'onJourneyStart', info: { } }],
|
|
1745
|
+
action: { type: 'setEnduserStatus', info: { status: 'Root' }, },
|
|
1746
|
+
})
|
|
1747
|
+
)
|
|
1748
|
+
await (
|
|
1749
|
+
sdk.api.automation_steps.createOne({
|
|
1750
|
+
journeyId: journey.id,
|
|
1751
|
+
events: [{ type: 'afterAction', info: {
|
|
1752
|
+
automationStepId: step.id,
|
|
1753
|
+
delay: TEST_DELAY / 1000,
|
|
1754
|
+
delayInMS: TEST_DELAY,
|
|
1755
|
+
unit: 'Seconds',
|
|
1756
|
+
} }],
|
|
1757
|
+
action: { type: 'setEnduserStatus', info: { status: 'Delayed Step' }, },
|
|
1758
|
+
})
|
|
1759
|
+
)
|
|
1760
|
+
// test empty events step doesn't get triggered or cause errors
|
|
1761
|
+
await (
|
|
1762
|
+
sdk.api.automation_steps.createOne({
|
|
1763
|
+
journeyId: journey.id,
|
|
1764
|
+
events: [],
|
|
1765
|
+
action: { type: 'setEnduserStatus', info: { status: 'INVARIANT_VIOLATION' }, },
|
|
1766
|
+
})
|
|
1767
|
+
)
|
|
1768
|
+
|
|
1769
|
+
// add to journey to trigger initial action
|
|
1770
|
+
await sdk.api.endusers.updateOne(enduser.id, { journeys: { [journey.id]: 'New' } }, { replaceObjectFields: true })
|
|
1771
|
+
await wait(undefined, 250)
|
|
1772
|
+
await async_test(
|
|
1773
|
+
`Root action triggered (only root)`,
|
|
1774
|
+
() => sdk.api.automated_actions.getSome({ filter: { enduserId: enduser.id }}),
|
|
1775
|
+
{ onResult: es => es.length === 1 }
|
|
1776
|
+
)
|
|
1777
|
+
await wait(undefined, 500)
|
|
1778
|
+
await async_test(
|
|
1779
|
+
`Next step not trigged early`,
|
|
1780
|
+
() => sdk.api.endusers.getOne(enduser.id),
|
|
1781
|
+
{ onResult: e => e.journeys?.[journey.id] !== 'Delayed Step' }
|
|
1782
|
+
)
|
|
1783
|
+
|
|
1784
|
+
await wait(undefined, 2 * TEST_DELAY) // wait long enough for automation to process and delay to pass
|
|
1785
|
+
await async_test(
|
|
1786
|
+
`Sequenced action triggered`,
|
|
1787
|
+
() => sdk.api.endusers.getOne(enduser.id),
|
|
1788
|
+
{ onResult: e => e.journeys?.[journey.id] === 'Delayed Step' }
|
|
1789
|
+
)
|
|
1790
|
+
|
|
1791
|
+
await Promise.all([
|
|
1792
|
+
sdk.api.journeys.deleteOne(journey.id),
|
|
1793
|
+
sdk.api.endusers.deleteOne(enduser.id),
|
|
1794
|
+
])
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
const sequenceTests = async () => {
|
|
1798
|
+
log_header("Automation Sequencing")
|
|
1799
|
+
|
|
1736
1800
|
const journey = await sdk.api.journeys.createOne({ title: 'test journey'})
|
|
1737
1801
|
const journey2 = await sdk.api.journeys.createOne({ title: 'other journey'})
|
|
1738
1802
|
|
|
@@ -1743,14 +1807,14 @@ const removeFromJourneyTests = async () => {
|
|
|
1743
1807
|
const step = await (
|
|
1744
1808
|
sdk.api.automation_steps.createOne({
|
|
1745
1809
|
journeyId: journey.id,
|
|
1746
|
-
|
|
1810
|
+
events: [{ type: 'onJourneyStart', info: { } }],
|
|
1747
1811
|
action: { type: 'setEnduserStatus', info: { status: 'Root' }, },
|
|
1748
1812
|
})
|
|
1749
1813
|
)
|
|
1750
1814
|
const step2 = await (
|
|
1751
1815
|
sdk.api.automation_steps.createOne({
|
|
1752
1816
|
journeyId: journey2.id,
|
|
1753
|
-
|
|
1817
|
+
events: [{ type: 'onJourneyStart', info: { } }],
|
|
1754
1818
|
action: { type: 'setEnduserStatus', info: { status: 'Root' }, },
|
|
1755
1819
|
})
|
|
1756
1820
|
)
|
|
@@ -1759,7 +1823,6 @@ const removeFromJourneyTests = async () => {
|
|
|
1759
1823
|
sdk.api.automated_actions.createOne({
|
|
1760
1824
|
journeyId,
|
|
1761
1825
|
automationStepId: step.id,
|
|
1762
|
-
cancelConditions: [],
|
|
1763
1826
|
enduserId: enduserId ?? enduser.id,
|
|
1764
1827
|
processAfter: Date.now() + 1000000, // add delay to make sure it doesn't happen
|
|
1765
1828
|
status: 'active',
|
|
@@ -1800,8 +1863,128 @@ const removeFromJourneyTests = async () => {
|
|
|
1800
1863
|
])
|
|
1801
1864
|
}
|
|
1802
1865
|
|
|
1866
|
+
export const cancelConditionsTests = async () => {
|
|
1867
|
+
log_header("Cancel Condition Tests")
|
|
1868
|
+
|
|
1869
|
+
const enduser = await sdk.api.endusers.createOne({ email: 'deletemeee@tellescope.com' })
|
|
1870
|
+
const journey = await sdk.api.journeys.createOne({ title: 'test journey '})
|
|
1871
|
+
const form = await sdk.api.forms.createOne({ title: 'test form' })
|
|
1872
|
+
const field = await sdk.api.form_fields.createOne({
|
|
1873
|
+
formId: form.id, title: 'question', type: 'string',
|
|
1874
|
+
previousFields: [{ type: 'root', info: {} }]
|
|
1875
|
+
})
|
|
1876
|
+
|
|
1877
|
+
// this action won't be fired, because patient isn't added to journey as part of tests
|
|
1878
|
+
const triggerStep = await sdk.api.automation_steps.createOne({
|
|
1879
|
+
journeyId: journey.id,
|
|
1880
|
+
events: [{ type: 'onJourneyStart', info: { } }],
|
|
1881
|
+
// in practice, this would send a form, so that the next step(s) could handle the response
|
|
1882
|
+
// but we don't want to send emails in testing, and can still attach this Id to a form response to test a trigger
|
|
1883
|
+
action: {
|
|
1884
|
+
type: 'setEnduserStatus',
|
|
1885
|
+
info: { status: 'start' },
|
|
1886
|
+
},
|
|
1887
|
+
})
|
|
1888
|
+
|
|
1889
|
+
const unsub = await sdk.api.automation_steps.createOne({
|
|
1890
|
+
journeyId: journey.id,
|
|
1891
|
+
events: [{
|
|
1892
|
+
type: 'formUnsubmitted',
|
|
1893
|
+
info: {
|
|
1894
|
+
automationStepId: triggerStep.id,
|
|
1895
|
+
delayInMS: 25, // should trigger
|
|
1896
|
+
delay: 0, unit: 'Seconds', // don't matter
|
|
1897
|
+
cancelConditions: [{ type: 'formResponse', info: { automationStepId: triggerStep.id }}]
|
|
1898
|
+
}
|
|
1899
|
+
}],
|
|
1900
|
+
action: {
|
|
1901
|
+
type: 'setEnduserStatus',
|
|
1902
|
+
info: { status: 'triggered' },
|
|
1903
|
+
},
|
|
1904
|
+
})
|
|
1905
|
+
|
|
1906
|
+
await sdk.api.automation_steps.createOne({
|
|
1907
|
+
journeyId: journey.id,
|
|
1908
|
+
events: [{
|
|
1909
|
+
type: 'afterAction',
|
|
1910
|
+
info: {
|
|
1911
|
+
automationStepId: unsub.id,
|
|
1912
|
+
delayInMS: 1000000, // ensure it doesn't trigger
|
|
1913
|
+
delay: 0, unit: 'Seconds', // don't matter
|
|
1914
|
+
cancelConditions: [{ type: 'formResponse', info: { automationStepId: triggerStep.id }}]
|
|
1915
|
+
}
|
|
1916
|
+
}],
|
|
1917
|
+
action: {
|
|
1918
|
+
type: 'setEnduserStatus',
|
|
1919
|
+
info: { status: 'violation 1' },
|
|
1920
|
+
},
|
|
1921
|
+
})
|
|
1922
|
+
|
|
1923
|
+
// a second followup to the unsub event (to create example of two actions with same cancel condition)
|
|
1924
|
+
await sdk.api.automation_steps.createOne({
|
|
1925
|
+
journeyId: journey.id,
|
|
1926
|
+
events: [{
|
|
1927
|
+
type: 'afterAction',
|
|
1928
|
+
info: {
|
|
1929
|
+
automationStepId: unsub.id,
|
|
1930
|
+
delayInMS: 1000000, // ensure it doesn't trigger
|
|
1931
|
+
delay: 0, unit: 'Seconds', // don't matter
|
|
1932
|
+
cancelConditions: [{ type: 'formResponse', info: { automationStepId: triggerStep.id }}]
|
|
1933
|
+
}
|
|
1934
|
+
}],
|
|
1935
|
+
action: {
|
|
1936
|
+
type: 'setEnduserStatus',
|
|
1937
|
+
info: { status: 'violation 2' },
|
|
1938
|
+
},
|
|
1939
|
+
})
|
|
1940
|
+
|
|
1941
|
+
const { accessCode } = await sdk.api.form_responses.prepare_form_response({
|
|
1942
|
+
formId: form.id,
|
|
1943
|
+
automationStepId: triggerStep.id, // must be included for trigger to happen
|
|
1944
|
+
enduserId: enduser.id
|
|
1945
|
+
})
|
|
1946
|
+
|
|
1947
|
+
// allow formUnsubmitted to trigger
|
|
1948
|
+
await wait(undefined, 2000) // allow background creation with generous pause
|
|
1949
|
+
|
|
1950
|
+
await async_test(
|
|
1951
|
+
`formUnsubmitted event with short delay is triggered`,
|
|
1952
|
+
() => sdk.api.endusers.getOne(enduser.id),
|
|
1953
|
+
{ onResult: e => e?.journeys?.[journey.id] === 'triggered' }
|
|
1954
|
+
)
|
|
1955
|
+
|
|
1956
|
+
// trigger cancel conditions
|
|
1957
|
+
await sdk.api.form_responses.submit_form_response({ accessCode, automationStepId: triggerStep.id, responses: [{
|
|
1958
|
+
answer: {
|
|
1959
|
+
type: 'string',
|
|
1960
|
+
value: 'answer'
|
|
1961
|
+
},
|
|
1962
|
+
fieldId: field.id,
|
|
1963
|
+
fieldTitle: field.title,
|
|
1964
|
+
}] })
|
|
1965
|
+
|
|
1966
|
+
await wait(undefined, 2000) // allow background creation with generous pause
|
|
1967
|
+
|
|
1968
|
+
await async_test(
|
|
1969
|
+
`Cancel conditions work for followup`,
|
|
1970
|
+
() => sdk.api.automated_actions.getSome(),
|
|
1971
|
+
{ onResult: as => as.length === 3
|
|
1972
|
+
&& as.find(a => a.automationStepId === unsub.id)?.status === 'finished'
|
|
1973
|
+
&& as.filter(a => a.status === 'cancelled').length === 2
|
|
1974
|
+
}
|
|
1975
|
+
)
|
|
1976
|
+
|
|
1977
|
+
await Promise.all([
|
|
1978
|
+
sdk.api.forms.deleteOne(form.id),
|
|
1979
|
+
sdk.api.journeys.deleteOne(journey.id),
|
|
1980
|
+
sdk.api.endusers.deleteOne(enduser.id)
|
|
1981
|
+
])
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1803
1984
|
const automation_events_tests = async () => {
|
|
1804
1985
|
log_header("Automation Events")
|
|
1986
|
+
await cancelConditionsTests()
|
|
1987
|
+
await sequenceTests()
|
|
1805
1988
|
await formEventTests()
|
|
1806
1989
|
await ticketEventTests()
|
|
1807
1990
|
await removeFromJourneyTests()
|
|
@@ -2650,6 +2833,7 @@ export const databases_tests = async () => {
|
|
|
2650
2833
|
|
|
2651
2834
|
const NO_TEST = () => {}
|
|
2652
2835
|
const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
2836
|
+
automation_steps: automation_events_tests,
|
|
2653
2837
|
calendar_event_templates: NO_TEST,
|
|
2654
2838
|
databases: databases_tests,
|
|
2655
2839
|
database_records: NO_TEST,
|
|
@@ -2675,7 +2859,6 @@ const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
|
2675
2859
|
form_responses: form_response_tests,
|
|
2676
2860
|
calendar_events: calendar_events_tests,
|
|
2677
2861
|
webhooks: NO_TEST, // tested separately,
|
|
2678
|
-
automation_steps: automation_events_tests,
|
|
2679
2862
|
sequence_automations: NO_TEST,
|
|
2680
2863
|
automated_actions: NO_TEST,
|
|
2681
2864
|
enduser_status_updates: status_update_tests,
|
|
@@ -254,7 +254,7 @@ const test_automation_webhooks = async () => {
|
|
|
254
254
|
}
|
|
255
255
|
await sdk.api.automation_steps.createOne({
|
|
256
256
|
journeyId: journey.id,
|
|
257
|
-
|
|
257
|
+
events: [{ type: "onJourneyStart", info: {} }],
|
|
258
258
|
action: testAction,
|
|
259
259
|
})
|
|
260
260
|
|
|
@@ -286,9 +286,9 @@ let CALENDAR_EVENT_WEBHOOK_COUNT = 0 //
|
|
|
286
286
|
const calendar_event_reminders_tests = async (isSubscribed: boolean) => {
|
|
287
287
|
log_header(`Calendar Event Reminders, isSubscribed=${isSubscribed}`)
|
|
288
288
|
|
|
289
|
-
const firstRemindAt =
|
|
289
|
+
const firstRemindAt = AUTOMATION_POLLING_DELAY_MS * 4
|
|
290
290
|
const secondRemindAt = AUTOMATION_POLLING_DELAY_MS * 2
|
|
291
|
-
const thirdRemindAt = AUTOMATION_POLLING_DELAY_MS *
|
|
291
|
+
const thirdRemindAt = AUTOMATION_POLLING_DELAY_MS * 0
|
|
292
292
|
const sampleCalendarEventReminders: CalendarEvent['reminders'] = [
|
|
293
293
|
{
|
|
294
294
|
msBeforeStartTime: firstRemindAt,
|
|
@@ -309,7 +309,7 @@ const calendar_event_reminders_tests = async (isSubscribed: boolean) => {
|
|
|
309
309
|
]
|
|
310
310
|
const calendarEvent = await sdk.api.calendar_events.createOne({
|
|
311
311
|
durationInMinutes: 10,
|
|
312
|
-
startTimeInMS: Date.now(),
|
|
312
|
+
startTimeInMS: Date.now() + firstRemindAt,
|
|
313
313
|
title: "Test Notifications",
|
|
314
314
|
reminders: sampleCalendarEventReminders,
|
|
315
315
|
})
|