@tellescope/sdk 1.2.0 → 1.2.3
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 +53 -2
- package/lib/cjs/enduser.d.ts.map +1 -1
- package/lib/cjs/enduser.js +5 -0
- package/lib/cjs/enduser.js.map +1 -1
- package/lib/cjs/sdk.d.ts +53 -1
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js +3 -0
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/session.d.ts +0 -1
- package/lib/cjs/session.d.ts.map +1 -1
- package/lib/cjs/session.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +376 -95
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/enduser.d.ts +53 -1
- package/lib/esm/enduser.d.ts.map +1 -1
- package/lib/esm/enduser.js +5 -0
- package/lib/esm/enduser.js.map +1 -1
- package/lib/esm/sdk.d.ts +53 -0
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js +3 -0
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/session.d.ts +0 -1
- package/lib/esm/session.d.ts.map +1 -1
- package/lib/esm/session.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +376 -95
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -10
- package/src/enduser.ts +17 -2
- package/src/sdk.ts +9 -0
- package/src/session.ts +1 -0
- package/src/tests/tests.ts +250 -14
package/src/tests/tests.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "@tellescope/types-client"
|
|
11
11
|
import {
|
|
12
12
|
AutomationAction,
|
|
13
|
+
FormResponseValue,
|
|
13
14
|
ModelName,
|
|
14
15
|
} from "@tellescope/types-models"
|
|
15
16
|
|
|
@@ -1008,13 +1009,29 @@ const chat_room_tests = async () => {
|
|
|
1008
1009
|
}
|
|
1009
1010
|
|
|
1010
1011
|
const chat_tests = async() => {
|
|
1012
|
+
log_header("Chat")
|
|
1013
|
+
|
|
1011
1014
|
const sdk2 = new Session({ host })
|
|
1012
1015
|
await sdk2.authenticate(nonAdminEmail, nonAdminPassword) // non-admin has access restrictions we want to test
|
|
1013
1016
|
|
|
1017
|
+
const enduser = await sdk.api.endusers.createOne({ email })
|
|
1018
|
+
await sdk.api.endusers.set_password({ id: enduser.id, password }).catch(console.error)
|
|
1019
|
+
await enduserSDK.authenticate(email, password).catch(console.error)
|
|
1020
|
+
|
|
1014
1021
|
const room = await sdk.api.chat_rooms.createOne({ type: 'internal', userIds: [userId] })
|
|
1015
1022
|
const chat = await sdk.api.chats.createOne({ roomId: room.id, message: "Hello!" })
|
|
1016
1023
|
const chat2 = await sdk.api.chats.createOne({ roomId: room.id, message: "Hello..." })
|
|
1017
1024
|
|
|
1025
|
+
const enduserRoom = await sdk.api.chat_rooms.createOne({ type: 'internal', userIds: [userId], enduserIds: [enduser.id] })
|
|
1026
|
+
await sdk.api.chats.createOne({ roomId: enduserRoom.id, message: 'enduser'})
|
|
1027
|
+
await enduserSDK.api.chats.createOne({ roomId: enduserRoom.id, message: 'enduser'})
|
|
1028
|
+
|
|
1029
|
+
await async_test(
|
|
1030
|
+
`get-chats for enduser`,
|
|
1031
|
+
() => enduserSDK.api.chats.getSome({ filter: { roomId: enduserRoom.id } }),
|
|
1032
|
+
{ onResult: c => c?.length === 2 }
|
|
1033
|
+
)
|
|
1034
|
+
|
|
1018
1035
|
// await async_test(
|
|
1019
1036
|
// `get-chat (without filter)`,
|
|
1020
1037
|
// () => sdk.api.chats.getOne(chat.id),
|
|
@@ -1110,6 +1127,11 @@ const chat_tests = async() => {
|
|
|
1110
1127
|
() => sdk.api.chats.getOne(chat2Null.id),
|
|
1111
1128
|
{ onResult: c => c.replyId === null }
|
|
1112
1129
|
)
|
|
1130
|
+
|
|
1131
|
+
await Promise.all([
|
|
1132
|
+
sdk.api.endusers.deleteOne(enduser.id),
|
|
1133
|
+
sdk.api.chat_rooms.deleteOne(enduserRoom.id),
|
|
1134
|
+
])
|
|
1113
1135
|
}
|
|
1114
1136
|
|
|
1115
1137
|
const enduserAccessTests = async () => {
|
|
@@ -1432,7 +1454,12 @@ const formEventTests = async () => {
|
|
|
1432
1454
|
const journey = await sdk.api.journeys.createOne({ title: 'test journey '})
|
|
1433
1455
|
const form = await sdk.api.forms.createOne({
|
|
1434
1456
|
title: 'test form',
|
|
1435
|
-
|
|
1457
|
+
})
|
|
1458
|
+
const field = await sdk.api.form_fields.createOne({
|
|
1459
|
+
formId: form.id,
|
|
1460
|
+
title: 'question',
|
|
1461
|
+
type: 'string',
|
|
1462
|
+
previousFields: [{ type: 'root', info: {} }]
|
|
1436
1463
|
})
|
|
1437
1464
|
|
|
1438
1465
|
const triggerStep = await sdk.api.automation_steps.createOne({
|
|
@@ -1460,8 +1487,19 @@ const formEventTests = async () => {
|
|
|
1460
1487
|
const { accessCode: acNoStep } = await sdk.api.form_responses.prepare_form_response({ formId: form.id, enduserId: enduser.id })
|
|
1461
1488
|
const { accessCode: acStep } = await sdk.api.form_responses.prepare_form_response({ formId: form.id, enduserId: enduser.id })
|
|
1462
1489
|
|
|
1463
|
-
|
|
1464
|
-
|
|
1490
|
+
const testResponse: FormResponseValue = {
|
|
1491
|
+
answer: {
|
|
1492
|
+
type: 'string',
|
|
1493
|
+
value: 'answer'
|
|
1494
|
+
},
|
|
1495
|
+
fieldId: field.id,
|
|
1496
|
+
fieldTitle: field.title,
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
const { formResponse } = await sdk.api.form_responses.submit_form_response({ accessCode: acNoStep, responses: [testResponse] })
|
|
1500
|
+
assert(objects_equivalent(formResponse.responses, [testResponse]), 'bad form resonse returned', 'form response returned correctly')
|
|
1501
|
+
|
|
1502
|
+
await sdk.api.form_responses.submit_form_response({ accessCode: acStep, automationStepId: triggerStep.id, responses: [testResponse] })
|
|
1465
1503
|
await wait(undefined, 250) // allow background creation with generous pause
|
|
1466
1504
|
|
|
1467
1505
|
await async_test(
|
|
@@ -1606,10 +1644,81 @@ const ticketEventTests = async () => {
|
|
|
1606
1644
|
])
|
|
1607
1645
|
}
|
|
1608
1646
|
|
|
1647
|
+
const removeFromJourneyTests = async () => {
|
|
1648
|
+
log_header("Remove from Journey")
|
|
1649
|
+
|
|
1650
|
+
const journey = await sdk.api.journeys.createOne({ title: 'test journey'})
|
|
1651
|
+
const journey2 = await sdk.api.journeys.createOne({ title: 'other journey'})
|
|
1652
|
+
|
|
1653
|
+
const enduser = await sdk.api.endusers.createOne({ email: 'test@tellescope.com' })
|
|
1654
|
+
const enduser2 = await sdk.api.endusers.createOne({ email: 'test2@tellescope.com' })
|
|
1655
|
+
await sdk.api.endusers.updateOne(enduser.id, { journeys: { [journey.id]: 'Added', [journey2.id]: 'Added2' }})
|
|
1656
|
+
|
|
1657
|
+
const step = await (
|
|
1658
|
+
sdk.api.automation_steps.createOne({
|
|
1659
|
+
journeyId: journey.id,
|
|
1660
|
+
event: { type: 'onJourneyStart', info: { } },
|
|
1661
|
+
action: { type: 'setEnduserStatus', info: { status: 'Root' }, },
|
|
1662
|
+
})
|
|
1663
|
+
)
|
|
1664
|
+
const step2 = await (
|
|
1665
|
+
sdk.api.automation_steps.createOne({
|
|
1666
|
+
journeyId: journey2.id,
|
|
1667
|
+
event: { type: 'onJourneyStart', info: { } },
|
|
1668
|
+
action: { type: 'setEnduserStatus', info: { status: 'Root' }, },
|
|
1669
|
+
})
|
|
1670
|
+
)
|
|
1671
|
+
|
|
1672
|
+
const createAction = (journeyId: string, step: { id: string }, enduserId?: string) => (
|
|
1673
|
+
sdk.api.automated_actions.createOne({
|
|
1674
|
+
journeyId,
|
|
1675
|
+
automationStepId: step.id,
|
|
1676
|
+
cancelConditions: [],
|
|
1677
|
+
enduserId: enduserId ?? enduser.id,
|
|
1678
|
+
processAfter: Date.now() + 1000000, // add delay to make sure it doesn't happen
|
|
1679
|
+
status: 'active',
|
|
1680
|
+
event: { type: 'onJourneyStart', info: { } },
|
|
1681
|
+
action: { type: 'setEnduserStatus', info: { status: 'Test Status' }, },
|
|
1682
|
+
})
|
|
1683
|
+
)
|
|
1684
|
+
|
|
1685
|
+
const numberOfActions = 4
|
|
1686
|
+
for (let i = 0; i < numberOfActions; i++) {
|
|
1687
|
+
await createAction(journey.id, step);
|
|
1688
|
+
await createAction(journey2.id, step2);
|
|
1689
|
+
await createAction(journey.id, step, enduser2.id);
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
// remove from journey, should set all statuses to cancelled
|
|
1693
|
+
await sdk.api.endusers.updateOne(enduser.id, { journeys: { } }, { replaceObjectFields: true })
|
|
1694
|
+
await wait(undefined, 250)
|
|
1695
|
+
|
|
1696
|
+
await async_test(
|
|
1697
|
+
`Automated actions for handle ticket created`,
|
|
1698
|
+
() => sdk.api.automated_actions.getSome(),
|
|
1699
|
+
{ onResult: (actions => (
|
|
1700
|
+
// enduser removed from multiple journeys
|
|
1701
|
+
actions.filter(a => a.status === 'cancelled').length === numberOfActions * 2
|
|
1702
|
+
|
|
1703
|
+
// other enduser is unaffected
|
|
1704
|
+
&& actions.filter(a => a.status === 'active').length === numberOfActions
|
|
1705
|
+
))}
|
|
1706
|
+
)
|
|
1707
|
+
|
|
1708
|
+
|
|
1709
|
+
await Promise.all([
|
|
1710
|
+
sdk.api.journeys.deleteOne(journey.id),
|
|
1711
|
+
sdk.api.journeys.deleteOne(journey2.id),
|
|
1712
|
+
sdk.api.endusers.deleteOne(enduser.id),
|
|
1713
|
+
sdk.api.endusers.deleteOne(enduser2.id),
|
|
1714
|
+
])
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1609
1717
|
const automation_events_tests = async () => {
|
|
1610
1718
|
log_header("Automation Events")
|
|
1611
1719
|
await formEventTests()
|
|
1612
1720
|
await ticketEventTests()
|
|
1721
|
+
await removeFromJourneyTests()
|
|
1613
1722
|
|
|
1614
1723
|
}
|
|
1615
1724
|
|
|
@@ -1622,21 +1731,60 @@ const form_response_tests = async () => {
|
|
|
1622
1731
|
const enduser = await sdk.api.endusers.createOne({ email: "formresponse@tellescope.com" })
|
|
1623
1732
|
const form = await sdk.api.forms.createOne({
|
|
1624
1733
|
title: 'test form',
|
|
1625
|
-
fields: [{
|
|
1626
|
-
title: stringTitle,
|
|
1627
|
-
description: 'Enter a string',
|
|
1628
|
-
type: 'string',
|
|
1629
|
-
isOptional: false,
|
|
1630
|
-
intakeField: stringIntakeField
|
|
1631
|
-
}]
|
|
1632
1734
|
})
|
|
1735
|
+
assert(form.numFields === 0, 'numFields bad init', 'num fields on init')
|
|
1736
|
+
|
|
1737
|
+
const field = await sdk.api.form_fields.createOne({
|
|
1738
|
+
formId: form.id,
|
|
1739
|
+
title: stringTitle,
|
|
1740
|
+
description: 'Enter a string',
|
|
1741
|
+
type: 'string',
|
|
1742
|
+
isOptional: false,
|
|
1743
|
+
intakeField: stringIntakeField,
|
|
1744
|
+
previousFields: [{ type: 'root', info: {} }]
|
|
1745
|
+
})
|
|
1746
|
+
const field2 = await sdk.api.form_fields.createOne({
|
|
1747
|
+
formId: form.id,
|
|
1748
|
+
title: stringTitle,
|
|
1749
|
+
description: 'Enter a string',
|
|
1750
|
+
type: 'string',
|
|
1751
|
+
isOptional: false,
|
|
1752
|
+
intakeField: stringIntakeField,
|
|
1753
|
+
previousFields: [{ type: 'root', info: {} }]
|
|
1754
|
+
})
|
|
1755
|
+
await wait(undefined, 250)
|
|
1756
|
+
|
|
1757
|
+
await async_test(
|
|
1758
|
+
`numFields incremented on new field`,
|
|
1759
|
+
() => sdk.api.forms.getOne(form.id),
|
|
1760
|
+
{ onResult: f => f.numFields === 2},
|
|
1761
|
+
)
|
|
1762
|
+
|
|
1763
|
+
await sdk.api.form_fields.deleteOne(field2.id)
|
|
1764
|
+
await wait(undefined, 250)
|
|
1765
|
+
await async_test(
|
|
1766
|
+
`numFields decremented after delete`,
|
|
1767
|
+
() => sdk.api.forms.getOne(form.id),
|
|
1768
|
+
{ onResult: f => f.numFields === 1},
|
|
1769
|
+
)
|
|
1770
|
+
|
|
1771
|
+
|
|
1633
1772
|
// await sdk.api.automation_steps.createOne({
|
|
1634
1773
|
// event: { type: "formResponse", info: { formId: form.id } },
|
|
1635
1774
|
// action: { type: 'sendWebhook', info: { message: 'test' } },
|
|
1636
1775
|
// })
|
|
1637
1776
|
|
|
1638
1777
|
const { accessCode } = await sdk.api.form_responses.prepare_form_response({ formId: form.id, enduserId: enduser.id })
|
|
1639
|
-
await sdk.api.form_responses.submit_form_response({ accessCode, responses: [
|
|
1778
|
+
await sdk.api.form_responses.submit_form_response({ accessCode, responses: [
|
|
1779
|
+
{
|
|
1780
|
+
fieldTitle: 'doesnot matter',
|
|
1781
|
+
fieldId: field.id,
|
|
1782
|
+
answer: {
|
|
1783
|
+
type: 'string',
|
|
1784
|
+
value: stringResponse,
|
|
1785
|
+
},
|
|
1786
|
+
}
|
|
1787
|
+
]})
|
|
1640
1788
|
|
|
1641
1789
|
// const [triggeredAutomation] = await sdk.api.automated_actions.getSome()
|
|
1642
1790
|
const enduserWithUpdate = await sdk.api.endusers.getOne(enduser.id)
|
|
@@ -1645,7 +1793,7 @@ const form_response_tests = async () => {
|
|
|
1645
1793
|
// assert(triggeredAutomation?.event?.type === 'formResponse', 'no form response event', 'form response event triggered')
|
|
1646
1794
|
assert(enduserWithUpdate?.fields?.[stringIntakeField] === stringResponse, 'no enduser update', 'enduser updated')
|
|
1647
1795
|
assert(
|
|
1648
|
-
recordedResponse?.responses?.length === 1 && recordedResponse.responses[0]?.
|
|
1796
|
+
recordedResponse?.responses?.length === 1 && recordedResponse.responses[0]?.answer.value === stringResponse,
|
|
1649
1797
|
'response not recorded',
|
|
1650
1798
|
'response recorded'
|
|
1651
1799
|
)
|
|
@@ -2100,6 +2248,87 @@ const enduser_redaction_tests = async () => {
|
|
|
2100
2248
|
])
|
|
2101
2249
|
}
|
|
2102
2250
|
|
|
2251
|
+
const public_form_tests = async () => {
|
|
2252
|
+
log_header("Public Form")
|
|
2253
|
+
|
|
2254
|
+
const journey = await sdk.api.journeys.createOne({ title: 'test journey '})
|
|
2255
|
+
const nonPublicForm = await sdk.api.forms.createOne({
|
|
2256
|
+
title: 'test form',
|
|
2257
|
+
intakePhone: 'optional',
|
|
2258
|
+
})
|
|
2259
|
+
const form = await sdk.api.forms.createOne({
|
|
2260
|
+
title: 'test form',
|
|
2261
|
+
allowPublicURL: true,
|
|
2262
|
+
intakePhone: 'optional',
|
|
2263
|
+
})
|
|
2264
|
+
const submitInfo = {
|
|
2265
|
+
businessId: form.businessId,
|
|
2266
|
+
email: 'publicformtest@tellescope.com',
|
|
2267
|
+
formId: form.id,
|
|
2268
|
+
fname: 'sebastian',
|
|
2269
|
+
lname: 'coates',
|
|
2270
|
+
}
|
|
2271
|
+
const submitInfoNonPublic = { ...submitInfo, formId: nonPublicForm.id }
|
|
2272
|
+
|
|
2273
|
+
await async_test(
|
|
2274
|
+
'non-public form blocked',
|
|
2275
|
+
() => enduserSDK.api.form_responses. session_for_public_form(submitInfoNonPublic),
|
|
2276
|
+
handleAnyError,
|
|
2277
|
+
)
|
|
2278
|
+
await async_test(
|
|
2279
|
+
'no questions form blocked',
|
|
2280
|
+
() => enduserSDK.api.form_responses. session_for_public_form(submitInfo),
|
|
2281
|
+
handleAnyError,
|
|
2282
|
+
)
|
|
2283
|
+
|
|
2284
|
+
const field = await sdk.api.form_fields.createOne({
|
|
2285
|
+
formId: form.id,
|
|
2286
|
+
title: 'question',
|
|
2287
|
+
type: 'string',
|
|
2288
|
+
previousFields: [{ type: 'root', info: {} }]
|
|
2289
|
+
})
|
|
2290
|
+
const testResponse: FormResponseValue = {
|
|
2291
|
+
answer: {
|
|
2292
|
+
type: 'string',
|
|
2293
|
+
value: 'answer'
|
|
2294
|
+
},
|
|
2295
|
+
fieldId: field.id,
|
|
2296
|
+
fieldTitle: field.title,
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
// upserts enduser
|
|
2300
|
+
const responseInfo = await enduserSDK.api.form_responses. session_for_public_form(submitInfo)
|
|
2301
|
+
|
|
2302
|
+
// verify enduser is actually upserted
|
|
2303
|
+
const enduser = await sdk.api.endusers.getOne({ email: 'publicformtest@tellescope.com'})
|
|
2304
|
+
|
|
2305
|
+
// test case for existing enduser
|
|
2306
|
+
await enduserSDK.api.form_responses. session_for_public_form(submitInfo)
|
|
2307
|
+
|
|
2308
|
+
enduserSDK.setAuthToken(responseInfo.authToken)
|
|
2309
|
+
await enduserSDK.refresh_session() // should be allowed
|
|
2310
|
+
|
|
2311
|
+
// assert((enduserSDK.userInfo as any).allowedPaths.length === 3, 'allowed paths not preserved', 'allowed paths preserved after refresh')
|
|
2312
|
+
|
|
2313
|
+
await async_test(
|
|
2314
|
+
'enduser cannot use non-allowed path',
|
|
2315
|
+
() => enduserSDK.api.endusers.updateOne(enduserSDK.userInfo.id, { fields: { testFiedl: 'testValue' } }),
|
|
2316
|
+
handleAnyError,
|
|
2317
|
+
)
|
|
2318
|
+
|
|
2319
|
+
await async_test(
|
|
2320
|
+
'enduser can submit public form',
|
|
2321
|
+
() => enduserSDK.api.form_responses.submit_form_response({ accessCode: responseInfo.accessCode, responses: [testResponse] }),
|
|
2322
|
+
passOnAnyResult,
|
|
2323
|
+
)
|
|
2324
|
+
|
|
2325
|
+
await Promise.all([
|
|
2326
|
+
sdk.api.forms.deleteOne(form.id),
|
|
2327
|
+
sdk.api.journeys.deleteOne(journey.id),
|
|
2328
|
+
sdk.api.endusers.deleteOne(enduser.id),
|
|
2329
|
+
])
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2103
2332
|
const NO_TEST = () => {}
|
|
2104
2333
|
const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
2105
2334
|
chats: chat_tests,
|
|
@@ -2118,6 +2347,7 @@ const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
|
2118
2347
|
meetings: meetings_tests,
|
|
2119
2348
|
notes: NO_TEST,
|
|
2120
2349
|
forms: NO_TEST,
|
|
2350
|
+
form_fields: NO_TEST,
|
|
2121
2351
|
form_responses: form_response_tests,
|
|
2122
2352
|
calendar_events: calendar_events_tests,
|
|
2123
2353
|
webhooks: NO_TEST, // tested separately,
|
|
@@ -2133,6 +2363,7 @@ const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
|
2133
2363
|
managed_content_records: NO_TEST,
|
|
2134
2364
|
post_comments: NO_TEST,
|
|
2135
2365
|
post_likes: NO_TEST,
|
|
2366
|
+
organizations: NO_TEST,
|
|
2136
2367
|
};
|
|
2137
2368
|
|
|
2138
2369
|
(async () => {
|
|
@@ -2145,6 +2376,7 @@ const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
|
2145
2376
|
])
|
|
2146
2377
|
await setup_tests()
|
|
2147
2378
|
await multi_tenant_tests() // should come right after setup tests
|
|
2379
|
+
await public_form_tests()
|
|
2148
2380
|
await search_tests()
|
|
2149
2381
|
await badInputTests()
|
|
2150
2382
|
await filterTests()
|
|
@@ -2155,9 +2387,13 @@ const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
|
2155
2387
|
await enduser_session_tests()
|
|
2156
2388
|
await role_based_access_tests()
|
|
2157
2389
|
await enduser_redaction_tests()
|
|
2158
|
-
} catch(err) {
|
|
2390
|
+
} catch(err: any) {
|
|
2159
2391
|
console.error("Failed during custom test")
|
|
2160
|
-
|
|
2392
|
+
if (err.message && err.info) {
|
|
2393
|
+
console.error(err.message, JSON.stringify(err.info, null, 2))
|
|
2394
|
+
} else {
|
|
2395
|
+
console.error(err)
|
|
2396
|
+
}
|
|
2161
2397
|
process.exit(1)
|
|
2162
2398
|
}
|
|
2163
2399
|
|