@tellescope/sdk 1.69.4 → 1.70.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.
@@ -4220,7 +4220,7 @@ export const self_serve_appointment_booking_tests = async () => {
4220
4220
  await sdk.api.users.updateOne(sdk.userInfo.id, {
4221
4221
  weeklyAvailabilities: [
4222
4222
  {
4223
- dayOfWeekStartingSundayIndexedByZero,
4223
+ dayOfWeekStartingSundayIndexedByZero: 0,
4224
4224
  startTimeInMinutes: 60 * 12, // noon,
4225
4225
  endTimeInMinutes: 60 * 13, // 1pm,
4226
4226
  },
@@ -4232,7 +4232,7 @@ export const self_serve_appointment_booking_tests = async () => {
4232
4232
  await sdkNonAdmin.api.users.updateOne(sdkNonAdmin.userInfo.id, {
4233
4233
  weeklyAvailabilities: [
4234
4234
  {
4235
- dayOfWeekStartingSundayIndexedByZero, // sunday
4235
+ dayOfWeekStartingSundayIndexedByZero: 0,
4236
4236
  startTimeInMinutes: 60 * 12, // noon,
4237
4237
  endTimeInMinutes: 60 * 14, // 2pm,
4238
4238
  },
@@ -4245,7 +4245,7 @@ export const self_serve_appointment_booking_tests = async () => {
4245
4245
  const multiSlots = await enduserSDK.api.calendar_events.get_appointment_availability({
4246
4246
  calendarEventTemplateId: event30min.id,
4247
4247
  from: new Date(Date.now()),
4248
- to: new Date(Date.now() + 8 * 24 * 60 * 60 * 1000),
4248
+ to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
4249
4249
  multi: true,
4250
4250
  userIds: [sdk.userInfo.id, sdkNonAdmin.userInfo.id]
4251
4251
  })
@@ -6065,6 +6065,213 @@ const test_weighted_round_robin = async () => {
6065
6065
  })
6066
6066
  }
6067
6067
 
6068
+ const enduser_access_tags_tests = async () => {
6069
+ log_header("enduser_access_tags_tests")
6070
+
6071
+ const matchTag = 'Access'
6072
+ const dontMatchTag = 'No Access'
6073
+
6074
+ const matchEnduser = await sdk.api.endusers.createOne({ accessTags: [matchTag]})
6075
+ const matchMultiTagEnduser = await sdk.api.endusers.createOne({ accessTags: [matchTag, dontMatchTag]})
6076
+ const dontMatchEnduser = await sdk.api.endusers.createOne({ accessTags: [dontMatchTag]})
6077
+ const matchTicket = await sdk.api.tickets.createOne({ enduserId: matchEnduser.id, title: 'ticket' })
6078
+ const dontMatchTicket = await sdk.api.tickets.createOne({ enduserId: dontMatchEnduser.id, title: 'ticket' })
6079
+
6080
+ // start with disabled setting an no tags on non-admin
6081
+ await sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { tags: [] }, { replaceObjectFields: true })
6082
+ await sdk.api.organizations.updateOne(sdkNonAdmin.userInfo.businessId, {
6083
+ settings: { endusers: { enableAccessTags: false } }
6084
+ })
6085
+ await sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword) // ensure enableAccessTags setting stored correctly on jwt
6086
+ await async_test(`Setting disabled, no tags, list`, sdkNonAdmin.api.endusers.getSome, { onResult: r => r.length === 0 })
6087
+ await async_test(`Setting disabled, matchEnduser`, () => sdkNonAdmin.api.endusers.getOne(matchEnduser.id), handleAnyError)
6088
+ await async_test(`Setting disabled, dontMatchEnduser`, () => sdkNonAdmin.api.endusers.getOne(dontMatchEnduser.id), handleAnyError)
6089
+ await async_test(`Setting disabled, no tags, tickets`, sdkNonAdmin.api.tickets.getSome, { onResult: r => r.length === 0 })
6090
+ await async_test(`Setting disabled, matchEnduser ticket`, () => sdkNonAdmin.api.tickets.getOne(matchTicket.id), handleAnyError)
6091
+ await async_test(`Setting disabled, dontMatchEnduser ticket`, () => sdkNonAdmin.api.tickets.getOne(dontMatchTicket.id), handleAnyError)
6092
+ await async_test(
6093
+ `tickets filter enduser valid`,
6094
+ () => sdkNonAdmin.api.tickets.getSome({ filter: { enduserId: matchEnduser.id }}), {
6095
+ onResult: r => r.length === 0
6096
+ })
6097
+ await async_test(
6098
+ `tickets filter enduser invalid`,
6099
+ () => sdkNonAdmin.api.tickets.getSome({ filter: { enduserId: dontMatchEnduser.id }}), {
6100
+ onResult: r => r.length === 0
6101
+ })
6102
+
6103
+
6104
+ // enable setting, disable tags
6105
+ await sdk.api.organizations.updateOne(sdkNonAdmin.userInfo.businessId, {
6106
+ settings: { endusers: { enableAccessTags: true } }
6107
+ })
6108
+ await sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword) // ensure enableAccessTags setting stored correctly on jwt
6109
+ await async_test(`enable setting, disable tags`, sdkNonAdmin.api.endusers.getSome, { onResult: r => r.length === 0 })
6110
+ await async_test(`enable setting, matchEnduser`, () => sdkNonAdmin.api.endusers.getOne(matchEnduser.id), handleAnyError)
6111
+ await async_test(`enable setting, dontMatchEnduser`, () => sdkNonAdmin.api.endusers.getOne(dontMatchEnduser.id), handleAnyError)
6112
+ await async_test(`enable setting, no tags, tickets`, sdkNonAdmin.api.tickets.getSome, { onResult: r => r.length === 0 })
6113
+ await async_test(`enable setting, matchEnduser ticket`, () => sdkNonAdmin.api.tickets.getOne(matchTicket.id), handleAnyError)
6114
+ await async_test(`enable setting, dontMatchEnduser ticket`, () => sdkNonAdmin.api.tickets.getOne(dontMatchTicket.id), handleAnyError)
6115
+ await async_test(
6116
+ `tickets filter enduser valid`,
6117
+ () => sdkNonAdmin.api.tickets.getSome({ filter: { enduserId: matchEnduser.id }}), {
6118
+ onResult: r => r.length === 0
6119
+ })
6120
+ await async_test(
6121
+ `tickets filter enduser invalid`,
6122
+ () => sdkNonAdmin.api.tickets.getSome({ filter: { enduserId: dontMatchEnduser.id }}), {
6123
+ onResult: r => r.length === 0
6124
+ })
6125
+
6126
+
6127
+ // disable setting, enable tags
6128
+ await sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { tags: [matchTag] }, { replaceObjectFields: true })
6129
+ await sdk.api.organizations.updateOne(sdkNonAdmin.userInfo.businessId, {
6130
+ settings: { endusers: { enableAccessTags: false } }
6131
+ })
6132
+ await sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword) // ensure enableAccessTags setting stored correctly on jwt
6133
+ await async_test(`disable setting, enable tags`, sdkNonAdmin.api.endusers.getSome, { onResult: r => r.length === 0 })
6134
+ await async_test(`disable setting, matchEnduser`, () => sdkNonAdmin.api.endusers.getOne(matchEnduser.id), handleAnyError)
6135
+ await async_test(`disable setting, dontMatchEnduser`, () => sdkNonAdmin.api.endusers.getOne(dontMatchEnduser.id), handleAnyError)
6136
+ await async_test(`disable setting, enable tags, tickets`, sdkNonAdmin.api.tickets.getSome, { onResult: r => r.length === 0 })
6137
+ await async_test(`disable setting, matchEnduser ticket`, () => sdkNonAdmin.api.tickets.getOne(matchTicket.id), handleAnyError)
6138
+ await async_test(`disable setting, dontMatchEnduser ticket`, () => sdkNonAdmin.api.tickets.getOne(dontMatchTicket.id), handleAnyError)
6139
+ await async_test(
6140
+ `tickets filter enduser valid`,
6141
+ () => sdkNonAdmin.api.tickets.getSome({ filter: { enduserId: matchEnduser.id }}), {
6142
+ onResult: r => r.length === 0
6143
+ })
6144
+ await async_test(
6145
+ `tickets filter enduser invalid`,
6146
+ () => sdkNonAdmin.api.tickets.getSome({ filter: { enduserId: dontMatchEnduser.id }}), {
6147
+ onResult: r => r.length === 0
6148
+ })
6149
+
6150
+
6151
+ // enabled setting AND tags (keeps tags enabled)
6152
+ await sdk.api.organizations.updateOne(sdkNonAdmin.userInfo.businessId, {
6153
+ settings: { endusers: { enableAccessTags: true } }
6154
+ })
6155
+ await sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword) // ensure enableAccessTags setting stored correctly on jwt
6156
+ await async_test(`Access by tag with setting works`, sdkNonAdmin.api.endusers.getSome, {
6157
+ onResult: r => r.length === 2 && !r.find(e => e.id === dontMatchEnduser.id)
6158
+ })
6159
+ await async_test(`access matchEnduser`, () => sdkNonAdmin.api.endusers.getOne(matchEnduser.id), passOnAnyResult)
6160
+ await async_test(`access dontMatchEnduser bad`, () => sdkNonAdmin.api.endusers.getOne(dontMatchEnduser.id), handleAnyError)
6161
+ await async_test(`access setting, no tags, tickets`, sdkNonAdmin.api.tickets.getSome, {
6162
+ onResult: r => r.length === 1 && !r.find(t => t.id === dontMatchTicket.id)
6163
+ })
6164
+ await async_test(`access, matchEnduser ticket`, () => sdkNonAdmin.api.tickets.getOne(matchTicket.id), passOnAnyResult)
6165
+ await async_test(`access, dontMatchEnduser ticket`, () => sdkNonAdmin.api.tickets.getOne(dontMatchTicket.id), handleAnyError)
6166
+ await async_test(
6167
+ `tickets filter enduser valid`,
6168
+ () => sdkNonAdmin.api.tickets.getSome({ filter: { enduserId: matchEnduser.id }}), {
6169
+ onResult: r => r.length === 1
6170
+ })
6171
+ await async_test(
6172
+ `tickets filter enduser invalid`,
6173
+ () => sdkNonAdmin.api.tickets.getSome({ filter: { enduserId: dontMatchEnduser.id }}), {
6174
+ onResult: r => r.length === 0
6175
+ })
6176
+
6177
+ await async_test(`Non-admin can't update tags`,
6178
+ () => sdkNonAdmin.api.users.updateOne(sdkNonAdmin.userInfo.id, { tags: ['new tag'] }),
6179
+ handleAnyError
6180
+ )
6181
+ await async_test(`Non-admin can't update tags (with other updates)`,
6182
+ () => sdkNonAdmin.api.users.updateOne(sdkNonAdmin.userInfo.id, { tags: ['new tag'], bio: '' }),
6183
+ handleAnyError
6184
+ )
6185
+ await async_test(`Non-admin can update other fields`,
6186
+ () => sdkNonAdmin.api.users.updateOne(sdkNonAdmin.userInfo.id, { bio: '' }),
6187
+ passOnAnyResult
6188
+ )
6189
+
6190
+ // cleanup
6191
+ await sdk.api.organizations.updateOne(sdkNonAdmin.userInfo.businessId, {
6192
+ settings: { endusers: { enableAccessTags: false } }
6193
+ })
6194
+ await sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { tags: [] }, { replaceObjectFields: true })
6195
+ await sdkNonAdmin.refresh_session()
6196
+ await Promise.all([
6197
+ sdk.api.endusers.deleteOne(matchEnduser.id),
6198
+ sdk.api.endusers.deleteOne(matchMultiTagEnduser.id),
6199
+ sdk.api.endusers.deleteOne(dontMatchEnduser.id),
6200
+ ])
6201
+ }
6202
+
6203
+ const unique_strings_tests = async () => {
6204
+ log_header("unique_strings test")
6205
+
6206
+ const e = await sdk.api.endusers.createOne({ assignedTo: ['1', '2', '2', '1', '3']})
6207
+ await async_test(`Duplicate care team assignments are prevented`,
6208
+ () => sdk.api.endusers.getOne(e.id),
6209
+ { onResult: e => e.assignedTo?.length === 3 && e.assignedTo.includes('1') && e.assignedTo.includes('2') && e.assignedTo.includes('3' )}
6210
+ )
6211
+
6212
+ // attempt to push duplicates of each
6213
+ await sdk.api.endusers.updateOne(e.id, { assignedTo: ['1', '2', '3'] }, { replaceObjectFields: false })
6214
+ await async_test(`Duplicate care team assignments are prevented (update)`,
6215
+ () => sdk.api.endusers.getOne(e.id),
6216
+ { onResult: e => e.assignedTo?.length === 3 && e.assignedTo.includes('1') && e.assignedTo.includes('2') && e.assignedTo.includes('3' )}
6217
+ )
6218
+
6219
+ // validate setting empty is allowed
6220
+ await async_test(`Setting empty is still allowed`,
6221
+ () => sdk.api.endusers.updateOne(e.id, { assignedTo: [] }, { replaceObjectFields: true }),
6222
+ passOnAnyResult
6223
+ )
6224
+
6225
+ return await Promise.all([
6226
+ sdk.api.endusers.deleteOne(e.id),
6227
+ ])
6228
+ }
6229
+
6230
+ const marketing_email_unsubscribe_tests = async () => {
6231
+ log_header("marketing_email_unsubscribe_tests")
6232
+
6233
+ const e = await sdk.api.endusers.createOne({ email: 'test@tellescope.com' })
6234
+ await async_test(
6235
+ `Non-marketing email good`,
6236
+ () => sdk.api.emails.createOne({ logOnly: true, subject: '', enduserId: e.id, textContent: '', HTMLContent: '' }),
6237
+ passOnAnyResult
6238
+ )
6239
+ await async_test(
6240
+ `Marketing email good when subscribed`,
6241
+ () => sdk.api.emails.createOne({ logOnly: true, isMarketing: true, subject: '', enduserId: e.id, textContent: '', HTMLContent: '' }),
6242
+ passOnAnyResult
6243
+ )
6244
+
6245
+ // attempt to push duplicates of each
6246
+ await sdk.GET('/v1/unsubscribe', { enduserId: e.id })
6247
+ await async_test(
6248
+ `GET /v1/unsubscribe works`,
6249
+ () => sdk.api.endusers.getOne(e.id),
6250
+ { onResult: e => e.unsubscribedFromMarketing === true }
6251
+ )
6252
+
6253
+ await async_test(
6254
+ `Non-marketing email good`,
6255
+ () => sdk.api.emails.createOne({ logOnly: true, subject: '', enduserId: e.id, textContent: '', HTMLContent: '' }),
6256
+ passOnAnyResult
6257
+ )
6258
+ await async_test(
6259
+ `Marketing email bad when unsubscribed`,
6260
+ () => sdk.api.emails.createOne({ logOnly: true, isMarketing: true, subject: '', enduserId: e.id, textContent: '', HTMLContent: '' }),
6261
+ handleAnyError
6262
+ )
6263
+ await async_test(
6264
+ `Marketing email bad when unsubscribed (bulk)`,
6265
+ () => sdk.api.emails.createSome([{ logOnly: true, isMarketing: true, subject: '', enduserId: e.id, textContent: '', HTMLContent: '' }]),
6266
+ handleAnyError
6267
+ )
6268
+
6269
+
6270
+ return await Promise.all([
6271
+ sdk.api.endusers.deleteOne(e.id),
6272
+ ])
6273
+ }
6274
+
6068
6275
  (async () => {
6069
6276
  log_header("API")
6070
6277
 
@@ -6105,6 +6312,9 @@ const test_weighted_round_robin = async () => {
6105
6312
  await mfa_tests()
6106
6313
  await setup_tests()
6107
6314
  await multi_tenant_tests() // should come right after setup tests
6315
+ await marketing_email_unsubscribe_tests()
6316
+ await unique_strings_tests()
6317
+ await enduser_access_tags_tests()
6108
6318
  await self_serve_appointment_booking_tests()
6109
6319
  await alternate_phones_tests()
6110
6320
  await ticket_queue_tests()
Binary file